Post

Replies

Boosts

Views

Activity

Change in Watch 7 in rounded corners of WKInterfaceLabel or WKInterfaceGroup
When testing in simulator with Xcode 13, I noted a subtle difference in the display of WKInterfaceLabel between Watch series 6 and series 7. WKInterfaceLabel is in a WKInterfaceGroup. On Series 7: the text Fast Driving is clipped with round corner at top and bottom On Series 6, round clipping is much less (noticeable on leading F and D) I could not find what parameter has changed in IB nor how to change this round corner value. Nor why such a change ?
3
0
2.0k
Nov ’21
repeatCount in UIViewPropertyAnimator
I have a func to flash a view a number of times and execute closure at the end. The following code with UIView.setAnimationRepeatCount works OK: animation occurs the requested number of times and afterEnd closure executes at the end. func flashIt(repeated: Int, cycleTime: Double, delayed: Double = 5.0, afterEnd: (() -> Void)? = nil) { if repeated < 0 { return } let initAlpha = self.alpha UIView.animate(withDuration: cycleTime, delay: delayed, options:[.allowUserInteraction, .curveEaseInOut, .autoreverse, .repeat], animations: { UIView.setAnimationRepeatCount(Float(repeated)) self.alpha = 0.1 // Not 0.0, to allow user interaction }, completion: { (done: Bool) in self.alpha = initAlpha afterEnd?() } ) } To address UIView.setAnimationRepeatCount deprecation, I now try this (inspired by https://stackoverflow.com/questions/47496584/uiviewpropertyanimator-reverse-animation) func flashIt(repeated: Int, cycleTime: Double, delayed: Double = 5.0, afterEnd: (() -> Void)? = nil) { if repeated < 0 { return } let initAlpha = self.alpha let animator = UIViewPropertyAnimator(duration: cycleTime, curve: .linear) { self.alpha = 0.1 } animator.addCompletion { _ in let reverseAnimator = UIViewPropertyAnimator(duration: cycleTime, curve: .linear) { self.alpha = initAlpha } reverseAnimator.addCompletion { [self] _ in flashIt(repeated: repeated-1, cycleTime: cycleTime, delayed: 0) // without delay here } reverseAnimator.startAnimation() if repeated <= 1 { // 1 and not 0, otherwise an extra loop… afterEnd?() // Not called return } } animator.startAnimation(afterDelay: delayed) } The flash works, but afterEnd closure is never called. I've tried to call if repeated <= 1 { // 1 and not 0, otherwise an extra loop… afterEnd?() // Not called return } in other places, to no avail. What do I miss ? Is there a better and simpler way to have a RepeatCount with UIViewPropertyAnimator ?
3
0
1.5k
Jan ’22
App hangs when setting constraint to a very specific value (a width divided by 2).
I get a surprising crash when adapting constraints. Xcode 13.2.1 iOS 15.2 on simulator Here is the set up in storyboard: A subclass of UIView (PopoverView) to draw a popover like frame and label and button inside. PopoverView can set its arrow position all around, for instance on the right, so that popover will appear on the left of an object, or on the left, to appear on the right. Button tap is used to loop through the arrow position. I have defined constraints (and their IBOutlets), and notably for the centerX position of popoverView to centerX of the label. I adapt the value of the constraints in viewWillLayoutSubviews to position the popover in correct position relative to the label. Now the problem. To position the popover on the right of the label, I set its centerX constraint as follows in viewWillLayoutSubviews(): popoverCenterToLabelCenterConstraint.constant = (popoverLabel.frame.width + label.frame.width) / 2 That works OK To position the popover on the left of the label, I set its constraint as follows (offset the opposite value): popoverCenterToLabelCenterConstraint.constant = -(popoverLabel.frame.width + label.frame.width) / 2 I also tried: popoverCenterToLabelCenterConstraint.constant = -popoverLabel.frame.width / 2 - label.frame.width / 2 App does not crash but hangs, apparently in an infinite loop. Idem if I divide by 2.0 instead of 2 : label.frame.width / 2.0 The width of the label, at this point of code, is 92.33333333333333 So I replaced by the value directly: popoverCenterToLabelCenterConstraint.constant = -popoverLabel.frame.width / 2 - 46.2 and it works OK. Idem with 46.1 So the problem is not due to the position of popoverView If I replace the div by 2 by 2.01 : - popoverCenterToLabelCenterConstraint.constant = -popoverLabel.frame.width / 2 - label.frame.width / 2.01 it works !!!!!! Conclusion: it is the exact div by 2 that causes the hanging. What could be the reason for this strange behaviour ?
3
0
1.2k
Feb ’22
Handwritten text recognition working poorly on iOS 16 beta ?
That's a follow up of a previous thread. https://developer.apple.com/forums/thread/707130 I did some test on iOS 16 simulator with Xcode 14ß. Recognition is very poor. And recognition rate of some single letters (an L or an I for instance) is zero (literally). Same code worked better (success 50% for same single letters) with iOS 15.2. Did something change on iOS 16 ? I filed a bug report: Jun 7, 2022 at 3:28 PM – FB10066541
3
0
2.4k
Jan ’23
Button behaviour changes if position(x:y)
With this code, button is at the center of the view and message is logged only when tapping in the button 1. struct ContentView: View { 2. var body: some View { 3. 4. ZStack { 5. Button(action: { 6. print("Touched") 7. }) { 8. Image(systemName: "square.split.diagonal.2x2") 9. .font(.system(size: 24)) 10. .foregroundColor(.black) 11. // .position(x: 12, y: 12) 12. } 13. 14. } 15. .frame(width: 300, height: 300) 16. .background(Color.yellow) 17. } 18. } But if I uncomment line 11, the message is logged on tap anywhere in the view. How is it position() changes the behaviour ?
3
0
1.1k
Dec ’22
List issues with dynamic content
I have encountered the following problem with a List. The setup is as follows @State private var allItems : [SomeItem] @State private var selected   : SomeItem? // in the body List(allItems, $selection) { theItem in … } where SomeItem is a struct. When some properties of an item in allItems changes, the values that I read in theItem are not updated. Just as if old content was cached. I changed allItems to a computed var and everything works OK. I read this SO thread https://stackoverflow.com/questions/74083515/swiftui-list-item-not-updated-if-model-is-wrapped-in-state but that does not give a full explanation. So my questions: Is there effectively an issue here ? when is it safe to use a State var as the Content of List ? Is it OK (it seems) if the properties of items do not change ? It seems also OK if the list of allItems is modified (appended, reduced) without problem changing the properties of its elements. How to do if needed to change both allItems (append for instance) and change the properties of some items, as computed var cannot be modified. Hope the question is clear.
3
0
1.1k
Mar ’23
SwiftUI TUICursorUIViewService error
I get this error in console in a SwiftUI MacApp on Xcode 15.0.1 and MacOS 14.1.2 FAULT: <NSRemoteView: 0x11f03bc00 com.apple.TextInputUI.xpc.CursorUIViewService TUICursorUIViewService> determined it was necessary to configure <TUINSWindow: 0x11f1b2390> to support remote view vibrancy I found similar errors that seem to be harmless messages popping up: https://developer.apple.com/forums/thread/72133 No idea what can cause such message, even less how to correct it.
3
5
3.3k
Dec ’23
Why does the superview of a UITableViewController turns nil after unwindSegue ?
Here is the set up. I have a UITableViewController (controller 1), to which I get from a controller (0) As I need to add a searchView atop the tableView, I addSubview to the superview. This is done in viewWillAppear self.view.superview?.addSubview(searchView) // AboveTableView searchView.isHidden = true print("willAppear", self.view.superview, self.tableView.superview) It works perfectly well, I get: willAppear Optional(<UIViewControllerWrapperView: 0x103d2eef0; frame = (0 0; 393 852); autoresize = W+H; layer = <CALayer: From this VC, I segue to another VC (2) with a show segue and comes back with an unwindSegue to return to (1). Problem is that no, superviews are nil. @IBAction func unwindToTableViewController(_ sender: UIStoryboardSegue) { print("unwind", self.view.superview, self.tableView.superview) } gives unwind nil nil If I step back from this controller (1) to the controller (0) from which I segued and segue again to the TableViewController (1), everything works as expected. In addition, if I go from 1 -> 2 by instantiating (2), everything works OK when I unwind to (1). I know a solution is to refactor code replacing UITableViewController with a UIViewController and embed a TableView inside. But I would like to understand why my present design does not work.
3
0
1.2k
Dec ’23
Changing background colour of Button changes the container background
To change the background of a TextField, I simply apply: TextField("0.0", value: $p, format: .number) .textFieldStyle(PlainTextFieldStyle()) .background(.red) That does only work with plain style, but it works. Trying something similar on a button changes the container view background. The only solution I've found is to overlap with a Rectangle. How is it ? A SwiftUI bug ? A current limit of Swift ? A rationale for it ? There a better solution I've not found ?
3
0
565
Oct ’24
Change app language on Apple Watch simulator
I feel a bit dumb now. I once succeeded to change the language of an app on Watch simulator. So it is possible. And I'm not able to repeat (fool of me I did not took note of how I did it). I just remember it was simply through some language settings selection, may be rebooting the Mac, but not by changing anything in code. Does someone know how to do ?
3
0
515
Mar ’25
Capturing self instead of using self. in switch case in DispatchQueue causes compiler error
I have an @objC used for notification. kTag is an Int constant, fieldBeingEdited is an Int variable. The following code fails at compilation with error: Command CompileSwift failed with a nonzero exit code if I capture self (I edited code, to have minimal case) @objc func keyboardDone(_ sender : UIButton) { DispatchQueue.main.async { [self] () -> Void in switch fieldBeingEdited { case kTag : break default : break } } } If I explicitly use self, it compiles, even with self captured: @objc func keyboardDone(_ sender : UIButton) { DispatchQueue.main.async { [self] () -> Void in switch fieldBeingEdited { // <<-- no need for self here case self.kTag : break // <<-- self here default : break } } } This compiles as well: @objc func keyboardDone(_ sender : UIButton) { DispatchQueue.main.async { () -> Void in switch self.fieldBeingEdited { // <<-- no need for self here case self.kTag : break // <<-- self here default : break } } } Is it a compiler bug or am I missing something ?
3
0
427
Jun ’25
NSKeyedArchiving issue
I have a large code that I try to update to change deprecated APIs. In the former version, I used forWritingWith and forReadingWith let data = NSMutableData() let archiver = NSKeyedArchiver(forWritingWith: data) archiver.encode(myObject, forKey: theKey) if let data = NSMutableData(contentsOf: anURL) { let unarchiver = NSKeyedUnarchiver(forReadingWith: data as Data) let myObject = unarchiver.decodeObject(forKey: theKey) as! TheObjectType // <<-- returns the object That I changed to let data = NSMutableData() let archiver = NSKeyedArchiver(requiringSecureCoding: true) archiver.encode(myObject, forKey: theKey) if let data = NSMutableData(contentsOf: anURL) { do { let unarchiver = try NSKeyedUnarchiver(forReadingFrom: data as Data) let myObject = unarchiver.decodeObject(forKey: theKey) as? TheObjectType // <<-- This returns nil This builds correctly. But on execution, unarchiver.decodeObject now returns nil. I have searched extensively to find the cause to no avail. I may probably change the design to avoid NSKeyedArchiver, but that would be a huge refactoring. I probably miss something obvious. Could someone hint at the possible cause ?
3
0
118
2w
Array of Bool require NSNumber.self in NSKeyedArchiver decoding list of types
I decode an object with NSKeyedArchiver (SecureCoding): typealias BoolArray = Array<Array<Bool>> let val = decoder.decodeObject(of: NSArray.self, forKey: someKey) as? BoolArray I get the following log: *** -[NSKeyedUnarchiver validateAllowedClass:forKey:] allowed unarchiving safe plist type ''NSNumber' (0x204cdbeb8) [/System/Library/Frameworks/Foundation.framework]' for key 'NS.objects', even though it was not explicitly included in the client allowed classes set: '{( "'NSArray' (0x204cd5598) [/System/Library/Frameworks/CoreFoundation.framework]" )}'. This will be disallowed in the future. I changed by adding NSNumber.self in the list : let val = decoder.decodeObject(of: [NSArray.self, NSNumber.self], forKey: someKey) as? BoolArray No more warning in log. Is there a reason for this ?
3
0
100
1w
Can we decode twice in the same session with unarchiver?
In a class, I call the following (edited to simplify, but it matches the real case). If I do this: func getData() -> someClass? { _ = someURL.startAccessingSecurityScopedResource() if let data = NSData(contentsOf: someURL as URL) { do { let unarchiver = try NSKeyedUnarchiver(forReadingFrom: data as Data) print((unarchiver.decodeObject(of: [NSArray.self, someClass.self /* and few others*/], forKey: oneKey) as? someClass)?.aProperty) if let result = unarchiver.decodeObject(of: [NSArray.self, someClass.self /* same other types*/], forKey: oneKey) as? someClass { unarchiver.finishDecoding() print("unarchived success") return result } else { unarchiver.finishDecoding() print("unarchiving failed") return someClass() } } catch { return nil } } I get a failure on log : unarchiving failed But if I comment out the print(unarchiver.decodeObject) - line 8, it works and I get unarchived success // print((unarchiver.decodeObject(of: [NSArray.self, someClass.self /* and few others*/], forKey: oneKey) as? someClass)?.aProperty) However, when I do exactly the same for another class (I've compared line by line to be sure), it works even with the print statement. What could be happening here ?
3
0
100
1w