Thanks for the code.
I had to modify the imageAsset?.register check to the following as I could not use @Environment(.colorScheme) because the Struct was not a View, as in other part of the my code, which was in SwiftUI:
var osTheme: UIUserInterfaceStyle { return UIScreen.main.traitCollection.userInterfaceStyle }
qrImage = osTheme == .light ? lightImage : darkImage
But otherwise it worked. The code that I found in the mean time was compiling but didn't work, it was a SO example using the "CIFalseColor" filter:
var qrImage = UIImage(systemName: "xmark.circle") ?? UIImage()
let data = Data(text.utf8)
let filter = CIFilter.qrCodeGenerator()
filter.setValue(data, forKey: "inputMessage")
let transform = CGAffineTransform(scaleX: 2, y: 2)
if let outputImage = filter.outputImage?.transformed(by: transform) {
if let image = context.createCGImage(
outputImage,
from: outputImage.extent) {
qrImage = UIImage(cgImage: image)
let colorParameters = [
"inputColor0": CIColor(color: UIColor.black), // Foreground
"inputColor1": CIColor(color: UIColor.green) // Background]
let colored = outputImage.applyingFilter("CIFalseColor", parameters: colorParameters)
qrImage = UIImage(ciImage: colored)
}
}
return qrImage
Anyway, it does work now.
Many thanks !
I have managed to simulate Apple's Core Image "CIPixelate" filter working with a transition.
Prepare by trawling all SKNodes on the scene and moving them to an SKEffectNode, which allows the filter to be applied to all its children in one go. Then place each iteration from a loop e.g. 1-20 (sweetspot) in a DispatchQueue with enough time for the pixelation effect to seem real.
//ITERATE OVER EACH PIXELATION REQUEST TO CREATE AN ANIMATION
for num in 1...20 {
let seconds = 0.3 + 0.1 * Double(num)
DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {
effectNode.filter = CIFilter(name : "CIPixellate",
parameters : [kCIInputScaleKey: (num)])
}
}
Finish by calling the scene transition function after the filter has had enough time to complete (I probably should use a dependency operation) gives the desired impression.
ref : https://github.com/rHockWorks/PixelationTransition/
Post not yet marked as solved
This post can be removed as it has been reposted in the SpriteKit forum.
Post not yet marked as solved
Requiring more lines of readout text, at first I expanded on the existing logic with arbitrary restrictions of 20 chars per line, purging as necessary to give the illusion that the text was wrapping around each line. However, this sliced words up without a thought for human readability:if (i > 20) {
useLine2 = true
}
if (useLine2 == false) {
line1 = line1 + String(letter)
}
if (useLine2 == true && (i > 20 && i <= 40)) {
line2 = line2 + String(letter)
useLine3 = true
}
if (useLine3 == true && (i > 40 && i <= 60)) {
line3 = line3 + String(letter)
useLine4 = true
}After this I tried using the Split function, Map’s various functions like flatten and sort etc… none of which worked for me. In the end, taking cue from Maxim Shoustin’s work to parse each of the words in the plist into an array with each word as an element allowed me to still use the 20 char restriction to check the length of each element before committing it in a line of text, but not if it would need to be cut to fit i.e. no broken words:extension String {
func split(regex pattern: String) -> [String] {
guard let re = try? NSRegularExpression(pattern: pattern, options: [])
else { return [] }
let nsString = self as NSString // needed for range compatibility
let stop = ""
let modifiedString = re.stringByReplacingMatches(
in: self,
options: [],
range: NSRange(location: 0, length: nsString.length),
withTemplate: stop)
return modifiedString.components(separatedBy: stop)
}
}I had one of these for each SKLabel i.e. I needed 5 lines of text so I had 5 SKLabelNode declarations for each one:var inDepthDescriptionLabel1: SKLabelNode = SKLabelNode()Simply change the string variables to arrays of type string:var line1: String = “”
var line1: [String] = []Use the string extension code above to place each of the words in your plist entry into an array as elements e.g. [“an” “array” “as” “an” “element”], so “an” is counted as 2 chars and “element” is 7 chars:let textToInterrogate: [String] = inDepthDescriptionOutput.split(regex: "[ ]+")Here the initial loop will look over the first 20 chars from the array (plist text) for the first line of text of outputted text, which is easy enough, but then then the second will look for 40 chars and chop of the first 20, giving you the second 20:“itemInArray” takes one element (word) from the textToInterrogate (plist) array (e.g. “an” or “element”) and using the Joined method it will stitch the words back together with empty spaces to give the illusion that it is just plain text, but only those that fit within the 20 char limit (forget not that arrays are an ordered type, so the words will read back the in order that they were written in your plist!). Those first 20 chars are appended to the relevant line array, but the description property makes them look like a string value so it will read nicely when you send it to the SKLabel: for itemInArray in textToInterrogate {
if (line1.joined(separator: " ").count < 20) {
line1.append(itemInArray.description)
}
}
for itemInArray in textToInterrogate {
if (line2.joined(separator: " ").count < 40) {
line2.append(itemInArray.description)
}
}
line2.removeFirst(line1.endIndex)The second line of text to find (above) is a little more tricky as it will take the first 20 chars from line1 and deduct them from the beginning of line2 (this must be done outside of the loop) to give the impression than the next 20 words are being displayed, and not the first 40 form the array (you already have the first 20 on the first line of course) for itemInArray in textToInterrogate {
if (line3.joined(separator: " ").count < 60) {
line3.append(itemInArray.description)
}
}
line3.removeFirst(line1.endIndex)
line3.removeFirst(line2.endIndex)line3 is as before, only you are on the third batch of 20 chars (i.e. 60) and now need to deduct the first 20 chars and second 20 chars (i.e. 40 chars) from the first two lines of text to get to the end of line3’s 20 chars that you need form the array. Just keep repeating this until you have covered all the lines of text that you need.Now to display the text in the SKLabels: if let inDepthDescriptionField: SKLabelNode = self.camera?.childNode(withName: "InDepthDescription1") as? SKLabelNode {
if (inDepthDescriptionLabel1.text != nil) {
inDepthDescriptionLabel1.text = line1.joined(separator: " ")
}The above code (depending on how you decide to send data to your SKLabels) will check if there is an SKLabel present and if it is a SKLabel node, then finally if the text in the field is empty. If all tests pass then the 20 char text your sorted for line1 is sent from it’s array as text to be displayed without the quotation marks, but with a blank space between each of the elements (or words) so it reads like normal text to a human.It does work, you can use it as a fallback option for the iOS11 introduction of multiline text.
Post not yet marked as solved
UIBezierPath is a UIKit Class, which is quite high level, if I went down to CoreAnimation, or even CoreGraphics, I should be able to extract the data, but I'm not sure how to do that?
Thanks Claude31, I manaed to refactor my code by a third and by 50% in key area, but NSLayout constraints can only be taken so far with For Loops, and I don't think I will miss VFL. //Row: 2
let fromBottomR2 = calculatriceButtonsII["8", "9", "x"]
let toBottomR2 = calculatriceButtonsII["7", "7", "7"]
for (_, buttonFrom) in fromBottomR2.enumerated() {
for (_, buttonTo) in toBottomR2.enumerated() {
NSLayoutConstraint.activate([
buttonFrom.bottomAnchor.constraint(equalTo: buttonTo.bottomAnchor),
])
}
}I will periodically challenge myself as I improve into the future.
Post not yet marked as solved
I thought that was all about the different [colour blind] settings users innevitably configured, so that it would never match up with the case even if white pixels were as white as the case.
You mean draw boxes with the UI? I am looking to code everything. I know that a for loop can create several replica boxes, but I don't know how to assign say a corresponding count (0...9) for the number keys to each one, and then place them on the screen, that would be the kind of simplification I am looking to achieve as those are similar.
Post not yet marked as solved
I'm not sure what you mean, the black border on the iPhone is visible? I assumed that the off pixels were as black as the case's finish, so it would be the illuminated white pixels that measure of interruption between the two.
Post not yet marked as solved
Sounds like you've been working there too long 🙂Although black is black with OLED, an unused pixel is cheating my opinion - how true to white are the whites on the OLED iPhone display, say if you have a white case?Thanks!
Post not yet marked as solved
Not my idea: https://dribbble.com/shots/4511814-Traveler-App?1524563451I understand that blacks on OLED screens are now similar to that of the case, however I'm not sure about whites. But the idea of a seamless interface would be the goal.
Sorry for the delay.Suggestion ref: 35018924
Thank you Eskimo for your input, very nice to have official involvement.I meant toggle in a binary sense, either on or off. Of course you know more about this than I, but it seems like anything can be overcomplicated. I remember when I learned the shortcut for comment marker (yes, I know that too has several versions of itself: multiline comment and documentation comments) and wondered why existing comments had four strokes, but it seems to make sense upon detraction, less things for the compiler to keep track of.
I have to say, this is a very different experience to the usual forums.Another aspect (as someone with fresh eyes) I thought about with Enumerations was that they're inherently designed to be type-safe, the only way to make a mistake really is to initially declare a member incorrectly. So then, would it not be a great timesaver if any changed made to a member were automatically made on your behalf by the compiler as it's keeping track of everything?I suppose seasoned coders don't want anything changing without it being from their hands, dot-notation is about the limit perhaps, but I don't see why this would not be welcome?Thoughts?