Construct and manage graphical, event-driven user interfaces for iOS or tvOS apps using UIKit.

Posts under UIKit tag

200 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Ignore : Mistakenly posted a draft
Mistakenly posted a draft. Kindly ignore I’m trying to set the accessibilityActivationPoint directly on a UITableViewCell so that VoiceOver focuses on a specific button inside the cell. However, this approach doesn’t seem to work. Instead, when I override the accessibilityActivationPoint property inside the UITableViewCell subclass and return the desired point, it works as expected. Why doesn’t setting accessibilityActivationPoint directly on the cell work, but overriding it inside the cell does? Is there a recommended approach for handling this scenario? The following approach works, get { return convert(toggleSwitch.center, to: nil) } set{ super.accessibilityActivationPoint = newValue } }
0
0
14
4h
Printing NSTextStorage over multiple UITextView produces weird results
I would like to print a NSTextStorage on multiple pages and add annotations to the side margins corresponding to certain text ranges. For example, for all occurrences of # at the start of a line, the side margin should show an automatically increasing number. My idea was to create a NSLayoutManager and dynamically add NSTextContainer instances to it until all text is laid out. The layoutManager would then allow me to get the bounding rectangle of the interesting text ranges so that I can draw the corresponding numbers at the same height inside the side margin. This approach works well on macOS, but I'm having some issues on iOS. When running the code below in an iPad Simulator, I would expect that the print preview shows 3 pages, the first with the numbers 0-1, the second with the numbers 2-3, and the last one with the number 4. Instead the first page shows the number 4, the second one the numbers 2-4, and the last one the numbers 0-4. It's as if the pages are inverted, and each page shows the text starting at the correct location but always ending at the end of the complete text (and not the range assigned to the relative textContainer). I've created FB17026419. class ViewController: UIViewController { override func viewDidAppear(_ animated: Bool) { let printController = UIPrintInteractionController.shared let printPageRenderer = PrintPageRenderer() printPageRenderer.pageSize = CGSize(width: 100, height: 100) printPageRenderer.textStorage = NSTextStorage(string: (0..<5).map({ "\($0)" }).joined(separator: "\n"), attributes: [.font: UIFont.systemFont(ofSize: 30)]) printController.printPageRenderer = printPageRenderer printController.present(animated: true) { _, _, error in if let error = error { print(error.localizedDescription) } } } } class PrintPageRenderer: UIPrintPageRenderer, NSLayoutManagerDelegate { var pageSize: CGSize! var textStorage: NSTextStorage! private let layoutManager = NSLayoutManager() private var textViews = [UITextView]() override var numberOfPages: Int { if !Thread.isMainThread { return DispatchQueue.main.sync { [self] in numberOfPages } } printFormatters = nil layoutManager.delegate = self textStorage.addLayoutManager(layoutManager) if textStorage.length > 0 { let glyphRange = layoutManager.glyphRange(forCharacterRange: NSRange(location: textStorage.length - 1, length: 0), actualCharacterRange: nil) layoutManager.textContainer(forGlyphAt: glyphRange.location, effectiveRange: nil) } var page = 0 for textView in textViews { let printFormatter = textView.viewPrintFormatter() addPrintFormatter(printFormatter, startingAtPageAt: page) page += printFormatter.pageCount } return page } func layoutManager(_ layoutManager: NSLayoutManager, didCompleteLayoutFor textContainer: NSTextContainer?, atEnd layoutFinishedFlag: Bool) { if textContainer == nil { addPage() } } private func addPage() { let textContainer = NSTextContainer(size: pageSize) layoutManager.addTextContainer(textContainer) let textView = UITextView(frame: CGRect(origin: .zero, size: pageSize), textContainer: textContainer) textViews.append(textView) } }
Topic: UI Frameworks SubTopic: UIKit Tags:
0
0
9
23h
Correct way to run modal session?
My assumption has always been that [NSApp runModalForWindow:] runs a modal window in NSModalPanelRunLoopMode. However, while -[NSApplication _doModalLoop:peek:] seems to use NSModalPanelRunLoopMode when pulling out the next event to process via nextEventMatchingMask:untilDate:inMode:dequeue:, the current runloop doesn't seem to be running in that mode, so during -[NSApplication(NSEventRouting) sendEvent:] of the modal-specific event, NSRunLoop.currentRunLoop.currentMode returns kCFRunLoopDefaultMode. From what I can tell, this means that any event processing code that e.g. uses [NSTimer addTimer:forMode:] based on the current mode will register a timer that will not fire until the modal session ends. Is this a bug? Or if not, is the correct way to run a modal session something like this? [NSRunLoop.currentRunLoop performInModes:@[NSModalPanelRunLoopMode] block:^{ [NSApp runModalForWindow:window]; }]; [NSRunLoop.currentRunLoop limitDateForMode:NSModalPanelRunLoopMode]; Alternatively, if the mode of the runloop should stay the same, I've seen suggestions to run modal sessions like this: NSModalSession session = [NSApp beginModalSessionForWindow:theWindow]; for (;;) { if ([NSApp runModalSession:session] != NSModalResponseContinue) break; [NSRunLoop.currentRunLoop limitDateForMode:NSModalPanelRunLoopMode]; } [NSApp endModalSession:session]; Which would work around the fact that the timer/callbacks were scheduled in the "wrong" mode. But running NSModalPanelRunLoopMode during a modal session seems a bit scary. Won't that potentially break the modality?
0
0
19
1d
Metal triangle strips uniform opacity.
I have this drawing app that I have been working on for the past few years when I have free time. I recently rebuilt the app in Metal to build out other brushes and improve performance, need to render 10000s of lines in realtime. I’m running into this issue trying to create a uniform opacity per path. I have a solution but do not love it - as this is a realtime app and the solution could have some bottlenecks. If I just generate a triangle strip from touch points and do my best to smooth, resample, and handle miters I will always get some overlaps. See: To create a uniform opacity I render to an offscreen texture with blending disabled. I then pre-multiply the color and draw that texture to a composite texture with blending on (I do this per path). This works but gets tricky when you introduce a textured brush, the edges of the texture in the frag shader cut out the line. Pasted Graphic 1.png Solution: I discard below a threshold fragment float4 fragment_line(VertexOut in [[stage_in]], texture2d<float> texture [[ texture(0) ]]) { constexpr sampler s(coord::normalized, address::mirrored_repeat, filter::linear); float2 texCoord = in.texCoord; float4 texColor = texture.sample(s, texCoord); if (texColor.a < 0.01) discard_fragment(); // may be slow (from what I read) return in.color * texColor; } Better but still not perfect. Question: I'm looking for better ways to create a uniform opacity per path. I tried .max blending but that will cause no blending of other paths. Any tips, ideas, much appreciated. If this is too detailed of a question just achieve.
1
0
35
1d
tableView.dequeueReusableHeaderFooterView(withIdentifier: ) crashes on iPad only
I have created a custom class: class TarifsHeaderFooterView: UITableViewHeaderFooterView { …} With its init: override init(reuseIdentifier: String?) { super.init(reuseIdentifier: reuseIdentifier) configureContents() } I register the custom header view in viewDidLoad of the class using the tableView. Table delegate and data source are defined in storyboard. tarifsTableView.register(TarifsHeaderFooterView.self, forHeaderFooterViewReuseIdentifier: headerTarifsIdentifier) And call it: func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: headerTarifsIdentifier) as! TarifsHeaderFooterView That works on iPhone (simulators and devices). But it crashes on any iPad simulator, as tableView.dequeueReusableHeaderFooterView(withIdentifier: headerTarifsIdentifier) is found nil. What difference between iPhone and iPad do I miss that explains this crash ? PS: sorry for the messy message. It looks like the new "feature" of the forum to put a Copy code button on the code parts, causes the code sections to be put at the very end of the post, not at the place they should be.
1
0
32
2d
accessibilityActivationPoint Not Working When Set Directly on UITableViewCell
I’m trying to set the accessibilityActivationPoint directly on a UITableViewCell so that VoiceOver activate on a specific button inside the cell. However, this approach doesn’t seem to work. Instead, when I override the accessibilityActivationPoint property inside the UITableViewCell subclass and return the desired point, it works as expected. Why doesn’t setting accessibilityActivationPoint directly on the cell work, but overriding it inside the cell does? Is there a recommended approach for handling this scenario? The following approach works, override var accessibilityActivationPoint: CGPoint { get { return convert(toggleSwitch.center, to: nil) } set{ super.accessibilityActivationPoint = newValue } } but setting accessibility point directly not works private func configureAccessibility() { isAccessibilityElement = true accessibilityLabel = titleLabel.text accessibilityTraits = .toggleButton accessibilityActivationPoint = self.convert(toggleSwitch.center, to: self) accessibilityValue = toggleSwitch.accessibilityValue }
1
0
48
1d
Abnormal UI and Keyboard Behavior in iPhone App Running on iPadOS 18.x Built with Xcode 16
Case-ID: 12591306 Use Xcode 16.x to compile an iPhone demo app and run it on an iPad (iPadOS 18.x) device or simulator. Launch the iPhone app and activate Picture-in-Picture mode. Attempt to input text; the system keyboard does not appear. Compare the output of [[UIScreen mainScreen] bounds] before and after enabling Picture-in-Picture mode, notice the values change unexpectedly after enabling PiP. This issue can be consistently reproduced on iPadOS 18.x when running an app built with Xcode 16.0 to Xcode 16.3RC(16E137). Beginning April 24, 2025, apps uploaded to App Store Connect must be built with Xcode 16 or later using an SDK for iOS 18, iPadOS 18, tvOS 18, visionOS 2, or watchOS 11.Therefore, I urgently hope to receive a solution provided by Apple.
1
0
35
2d
UIAlertController sometimes does not call its UIAlertAction handler
The iOS app that I’m helping to develop displays the following behavior, observed on an iPad Pro (4th generation) running iOS 18.1.1: The app uses UIAlertController to show an action sheet with two buttons (defined by two UIAlertAction objects). Each button has a handler block, and the first thing each handler does is to log that it was called. When the user taps one of the buttons and the action sheet disappears, most of the time the appropriate UIAlertAction handler is called. But sometimes there is no log entry for either of the action handlers, nor does the app do anything else associated with the chosen button, in which case I conclude that the handler was not called. I want to emphasize that I’m describing instances of the same action sheet displayed by the same code. Most of the time the appropriate button handler is called, but sometimes the handler is not called. The uncalled handler problem occurs about once per hour during normal use of the app. The problem has continued to occur across many weeks of testing. What could cause UIAlertController not to call its action handler?
Topic: UI Frameworks SubTopic: UIKit Tags:
5
0
51
1d
accessibilityElements excludes the unlisted subviews – How to Fix?
I have a parent view containing 10 subviews. To control the VoiceOver navigation order, I set only a few elements in accessibilityElements. However, the remaining elements are not being focused or are completely inaccessible. Is this the expected behavior? If I only specify a subset of elements in accessibilityElements, does it exclude the rest? What’s the best way to ensure all elements remain accessible while customising the order?
2
0
69
2d
UIKit or SwiftUI First? Exploring the Best Hybrid Approach
UIKit and SwiftUI each have their own strengths and weaknesses: UIKit: More performant (e.g., UICollectionView). SwiftUI: Easier to create shiny UI and animations. My usual approach is to base my project on UIKit and use UIHostingController whenever I need to showcase visually rich UI or animations (such as in an onboarding presentation). So far, this approach has worked well for me—it keeps the project clean while solving performance concerns effectively. However, I was wondering: Has anyone tried the opposite approach? Creating a project primarily in SwiftUI, then embedding UIKit when performance is critical. If so, what has your experience been like? Would you recommend this approach? I'm considering this for my next project but am unsure how well it would work in practice.
1
0
34
2d
Writing tools options
Hi team, We have implemented a writing tool inside a WebView that allows users to type content in a textarea. When the "Show Writing Tools" button is clicked, an AI-powered editor opens. After clicking the "Rewrite" button, the AI modifies the text. However, when clicking the "Replace" button, the rewritten text does not update the original textarea. Kindly check and help me showButton.addTarget(self, action: #selector(showWritingTools(_:)), for: .touchUpInside) @available(iOS 18.2, *) optional func showWritingTools(_ sender: Any) Note: same cases working in TextView pfa
0
0
32
6d
SwiftUI Preview Fails to Load While Project Builds and Runs Fine: Alamofire Module Map Issue
I'm having an issue specifically with SwiftUI previews in my iOS project. The project builds and runs fine on devices and simulators (in Rosetta mode), but SwiftUI previews fail to load in both Rosetta and native arm64 simulator environments. The main error in the preview is related to the Alamofire dependency in my SiriKit Intents extension: Module map file '[DerivedData path]/Build/Products/Debug-iphonesimulator/Alamofire/Alamofire.modulemap' not found This error repeats for multiple Swift files within my SiriKit Intents extension. Additionally, I'm seeing: Cannot load underlying module for 'Alamofire Environment Xcode version: 16.2 macOS version: Sonoma 14.7 Swift version: 6.0.3 (swiftlang-6.0.3.1.10 clang-1600.0.30.1) Dependency management: CocoaPods Alamofire version: 5.8 My project is a large, older codebase that contains a mix of UIKit, Objective-C and Swift Architecture Issue: The project only builds successfully in Rosetta mode for simulators. SwiftUI previews are failing in both Rosetta and native arm64 environments. This suggests there may be a fundamental issue with how the preview system interacts with the project's architecture configuration. What I've Tried I've attempted several solutions without success: Cleaning the build folder (⇧⌘K and Option+⇧⌘K) Deleting derived data Reinstalling dependencies Restarting Xcode Removing and re-adding Alamofire
1
0
36
6d
UIContextMenuInteraction not working if view is originally offscreen
I’m having a weird UIKit problem. I have a bunch of views in a UIScrollView and I add a UIContextMenuInteraction to all of them when the view is first loaded. Because they're in a scroll view, only some of the views are initially visible. The interaction works great for any of the views that are initially on-screen, but if I scroll to reveal new subviews, the context menu interaction has no effect for those. I used Xcode's View Debugger to confirm that my interaction is still saved in the view's interactions property, even for views that were initially off-screen and were then scrolled in. What could be happening here?
Topic: UI Frameworks SubTopic: UIKit Tags:
0
0
20
1w
Unable to Add Accessibility Trait to UISegmentedControl
I’m trying to add the .header accessibility trait to a UISegmentedControl so that VoiceOver recognizes it accordingly. However, setting the trait using the following code doesn’t seem to have any effect: segmentControl.accessibilityTraits = segmentControl.accessibilityTraits.union(.header) Even after applying this, VoiceOver doesn’t announce it as a header. Is there any workaround or recommended approach to achieve this?
1
0
152
1w
Vibrancy effect not applied to context menu UIImages rendered in template mode
Our Apple TV provides UIImages with renderingMode forced to .alwaysTemplate (the images are also configured with "Render As" to "Template image" in the Asset catalog) to UIActions as UIMenuElement when building a UICollectionView UIContextMenuConfiguration. Problem: these images are not displayed with vibrancy effect by the system. The issue does not occur with system images (SVG from SF Catalog). Here is a screenshot showing the issue with custom images ("Trailer" and "Remove from favourites"): I don't know the underlying implementation of the context menu items image but UIImageView already implements the tintColorDidChange() method and the vibrancy should work if the UIImage is rendered as template. According to my tests, the vibrancy is correctly applied when using Symbols sets instead of Images sets but I understand that custom images rendered as template should support it as-well, shouldn't they?
2
0
110
1w
Regarding errors with UIToolbar and UIBarButtonItem set to UITextField
I set UIToolbar and UIBarButtonItem to UITextField placed on Xib, but when I run it on iOS18 iPad, the following error is output to Xcode Console, and UIPickerView set to UITextField.inputView is not displayed. Error: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number) to CoreGraphics API and this value is being ignored. Please fix this problem. If you want to see the backtrace, please set CG_NUMERICS_SHOW_BACKTRACE environmental variable. Backtrace: <CGPathAddLineToPoint+71> <+[UIBezierPath _continuousRoundedRectBezierPath:withRoundedCorners:cornerRadii:segments:smoothPillShapes:clampCornerRadii:] <+[UIBezierPath _continuousRoundedRectBezierPath:withRoundedCorners:cornerRadius:segments:]+175> <+[UIBezierPath _roundedRectBezierPath:withRoundedCorners:cornerRadius:segments:legacyCorners:]+338> <-[_UITextMagnifiedLoupeView layoutSubviews]+2233> <__56-[_UITextMagnifiedLoupeView _updateCloseLoupeAnimation:]_block_invoke+89> <+[UIView(UIViewAnimationWithBlocksPrivate) _modifyAnimationsWithPreferredFrameRateRange:updateReason:animations:]+166> <block_destroy_helper.269+92> <block_destroy_helper.269+92> <__swift_instantiateConcreteTypeFromMangledName+94289> <block_destroy_helper.269+126> <+[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:anima <block_destroy_helper.269+6763> <block_destroy_helper.269+10907> <-[_UITextMagnifiedLoupeView _updateCloseLoupeAnimation:]+389> <-[_UITextMagnifiedLoupeView setVisible:animated:completion:]+256> <-[UITextLoupeSession _invalidateAnimated:]+329> <-[UITextRefinementTouchBehavior textLoupeInteraction:gestureChangedWithState:location:translation:velocity: <-[UITextRefinementInteraction loupeGestureWithState:location:translation:velocity:modifierFlags:shouldCanc <-[UITextRefinementInteraction loupeGesture:]+701> <-[UIGestureRecognizerTarget _sendActionWithGestureRecognizer:]+71> <_UIGestureRecognizerSendTargetActions+100> <_UIGestureRecognizerSendActions+306> <-[UIGestureRecognizer _updateGestureForActiveEvents]+704> <_UIGestureEnvironmentUpdate+3892> <-[UIGestureEnvironment _updateForEvent:window:]+847> <-[UIWindow sendEvent:]+4937> <-[UIApplication sendEvent:]+525> <__dispatchPreprocessedEventFromEventQueue+1436> <__processEventQueue+8610> <updateCycleEntry+151> <_UIUpdateSequenceRun+55> <schedulerStepScheduledMainSection+165> <runloopSourceCallback+68> <__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__+17> <__CFRunLoopDoSource0+157> <__CFRunLoopDoSources0+293> <__CFRunLoopRun+960> <CFRunLoopRunSpecific+550> <GSEventRunModal+137> <-[UIApplication _run]+875> <UIApplicationMain+123> <__debug_main_executable_dylib_entry_point+63> 10d702478 204e57345 Type: Error | Timestamp: 2025-03-09 00:22:46.121407+09:00 | Process: FurusatoLocalCurrency | Library: CoreGraphics | Subsystem: com.apple.coregraphics | Category: Unknown process name | TID: 0x5c360 Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) ( "<NSAutoresizingMaskLayoutConstraint:0x600002202a30 h=--& v=--& _UIToolbarContentView:0x7fc2c6a5b8f0.width == 0 (active)>", "<NSLayoutConstraint:0x600002175e00 H:|-(0)-[_UIButtonBarStackView:0x7fc2c6817b10] (active, names: '|':_UIToolbarContentView:0x7fc2c6a5b8f0 )>", "<NSLayoutConstraint:0x600002175e50 H:[_UIButtonBarStackView:0x7fc2c6817b10]-(0)-| (active, names: '|':_UIToolbarContentView:0x7fc2c6a5b8f0 )>", "<NSLayoutConstraint:0x6000022019f0 'TB_Leading_Leading' H:|-(8)-[_UIModernBarButton:0x7fc2a5aa8920] (active, names: '|':_UIButtonBarButton:0x7fc2a5aa84d0 )>", "<NSLayoutConstraint:0x600002201a40 'TB_Trailing_Trailing' H:[_UIModernBarButton:0x7fc2a5aa8920]-(0)-| (active, names: '|':_UIButtonBarButton:0x7fc2a5aa84d0 )>", "<NSLayoutConstraint:0x600002201e50 'UISV-canvas-connection' UILayoutGuide:0x600003b7d420'UIViewLayoutMarginsGuide'.leading == _UIButtonBarButton:0x7fc2f57117f0.leading (active)>", "<NSLayoutConstraint:0x600002201ea0 'UISV-canvas-connection' UILayoutGuide:0x600003b7d420'UIViewLayoutMarginsGuide'.trailing == UIView:0x7fc2a5aac8e0.trailing (active)>", "<NSLayoutConstraint:0x6000022021c0 'UISV-spacing' H:[_UIButtonBarButton:0x7fc2f57117f0]-(0)-[UIView:0x7fc2a5aa8330] (active)>", "<NSLayoutConstraint:0x600002202210 'UISV-spacing' H:[UIView:0x7fc2a5aa8330]-(0)-[_UIButtonBarButton:0x7fc2a5aa84d0] (active)>", "<NSLayoutConstraint:0x600002202260 'UISV-spacing' H:[_UIButtonBarButton:0x7fc2a5aa84d0]-(0)-[UIView:0x7fc2a5aac8e0] (active)>", "<NSLayoutConstraint:0x600002176f30 'UIView-leftMargin-guide-constraint' H:|-(0)-[UILayoutGuide:0x600003b7d420'UIViewLayoutMarginsGuide'](LTR) (active, names: '|':_UIButtonBarStackView:0x7fc2c6817b10 )>", "<NSLayoutConstraint:0x600002176e40 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x600003b7d420'UIViewLayoutMarginsGuide']-(0)-|(LTR) (active, names: '|':_UIButtonBarStackView:0x7fc2c6817b10 )>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x600002201a40 'TB_Trailing_Trailing' H:[_UIModernBarButton:0x7fc2a5aa8920]-(0)-| (active, names: '|':_UIButtonBarButton:0x7fc2a5aa84d0 )> Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
Topic: UI Frameworks SubTopic: UIKit Tags:
0
0
46
1w
detecting modifier keys using UITextFieldDelegate protocol
I have a UITextField in my application, and I want to detect all the keys uniquely to perform all relevant task. However, there is some problem in cleanly identifying some of the keys. I m not able to identify the backspace key press in the textField(_:shouldChangeCharactersIn:replacementString:) method. Also I don't know how to detect the Caps Lock key. I am intending to so this because I want to perform some custom handling for some keys. Can someone help me with what is the way of detecting it under the recommendation from apple. Thanks in advance. Note: checking for replacementString parameter in shouldChangeCharactersIn method for empty does not help for backspace detection as it overlaps with other cases.
Topic: UI Frameworks SubTopic: UIKit Tags:
0
0
98
1w