Discuss the different user interface frameworks available for your app.

All subtopics
Posts under UI Frameworks topic

Post

Replies

Boosts

Views

Created

UIViewController memory leak with modal presentedViewController
Hi everyone, I'm encountering an unexpected behavior with modal presentations in UIKit. Here’s what happens: I have UIViewControllerA (let’s call it the "orange" VC) pushed onto a UINavigationController stack. I present UIViewControllerB (the "red" VC, inside its own UINavigationController as a .formSheet) modally over UIViewControllerA. After a short delay, I pop UIViewControllerA from the navigation stack. Issue: After popping UIViewControllerA, the modal UIViewControllerB remains visible on the screen and in memory. I expected that dismissing (popping) the presenting view controller would also dismiss the modal, but it stays. Expected Behavior: When UIViewControllerA (orange) is popped, I expect the modal UIViewControllerB (red) to be dismissed as well. Actual Behavior: The modal UIViewControllerB remains on screen and is not dismissed, even though its presenting view controller has been removed from the navigation stack. Video example: https://youtube.com/shorts/sttbd6p_r_c Question: Is this the expected behavior? If so, what is the recommended way to ensure that the modal is dismissed when its presenting view controller is removed from the navigation stack? Code snippet: class MainVC: UIViewController { private weak var orangeVC: UIViewController? override func viewDidLoad() { super.viewDidLoad() self.view.backgroundColor = .blue let dq = DispatchQueue.main dq.asyncAfter(deadline: .now() + 1) { [weak self] in let vc1 = UIViewController() vc1.view.backgroundColor = .orange vc1.modalPresentationStyle = .overCurrentContext self?.navigationController?.pushViewController(vc1, animated: true) self?.orangeVC = vc1 dq.asyncAfter(deadline: .now() + 1) { [weak self] in let vc2 = UIViewController() vc2.view.backgroundColor = .red vc2.modalPresentationStyle = .formSheet vc2.isModalInPresentation = true let nav = UINavigationController(rootViewController: vc2) if let sheet = nav.sheetPresentationController { sheet.detents = [.medium()] } self?.orangeVC?.present(nav, animated: true) dq.asyncAfter(deadline: .now() + 1) { [weak self] in self?.navigationController?.popViewController(animated: true) } } } } } Thank you for your help!
0
0
59
5d
Expandable cell in List View shows slowly after swiping to delete it
If the cell is expandable in List View, it will show slowly after deletion swipe. the image shows how it looks like when this issue happens and it should be easy to reproduce with this sample codes // Model for list items struct ListItem: Identifiable { let id = UUID() let title: String let createdDate: Date let description: String } struct ExpandableListView: View { // Sample constant data private let items: [ListItem] = [ ListItem( title: "First Item", createdDate: Date().addingTimeInterval(-86400 * 5), description: "This is a detailed description for the first item. It contains two lines of text to show when expanded." ), ListItem( title: "Second Item", createdDate: Date().addingTimeInterval(-86400 * 3), description: "This is a detailed description for the second item. It provides additional information about this entry." ), ListItem( title: "Third Item", createdDate: Date().addingTimeInterval(-86400 * 1), description: "This is a detailed description for the third item. Tap to expand and see more details here." ), ListItem( title: "Fourth Item", createdDate: Date(), description: "This is a detailed description for the fourth item. It shows comprehensive information when tapped." ) ] // Track which item is currently selected/expanded @State private var selectedItemId: UUID? = nil var body: some View { NavigationView { List { ForEach(items) { item in ExpandableCell( item: item, isExpanded: selectedItemId == item.id ) { // Handle tap - toggle selection withAnimation(.easeInOut(duration: 0.3)) { if selectedItemId == item.id { selectedItemId = nil } else { selectedItemId = item.id } } } } .onDelete { indexSet in for index in indexSet { print("delete \(items[index].title)") } } } .navigationTitle("Items") } } } struct ExpandableCell: View { let item: ListItem let isExpanded: Bool let onTap: () -> Void private var dateFormatter: DateFormatter { let formatter = DateFormatter() formatter.dateStyle = .medium formatter.timeStyle = .short return formatter } var body: some View { VStack(alignment: .leading, spacing: 8) { // Always visible: Title and Date HStack { VStack(alignment: .leading, spacing: 4) { Text(item.title) .font(.headline) .foregroundColor(.primary) Text(dateFormatter.string(from: item.createdDate)) .font(.caption) .foregroundColor(.secondary) } Spacer() // Chevron indicator Image(systemName: isExpanded ? "chevron.up" : "chevron.down") .foregroundColor(.secondary) .font(.caption) } // Expandable: Description (2 lines) if isExpanded { Text(item.description) .font(.body) .foregroundColor(.secondary) .lineLimit(2) .fixedSize(horizontal: false, vertical: true) .transition(.opacity.combined(with: .move(edge: .top))) .padding(.top, 4) } } .padding(.vertical, 8) .contentShape(Rectangle()) .onTapGesture { onTap() } } } #Preview { ExpandableListView() }
1
0
48
5d
Incorrect system color on popover view, and does not update while switching dark mode on iOS 26 beta 3
All system colors are displayed incorrectly on the popover view. Those are the same views present as a popover in light and dark mode. And those are the same views present as modal. And there is also a problem that when the popover is presented, switching to dark/light mode will not change the appearance. That affected all system apps. The following screenshot is already in dark mode. All those problem are occured on iOS 26 beta 3.
3
0
297
1w
Weird transparency in sidebar in iPad app
I have an iPad app with a classic sidebar. It's been working fine for years. Now with iPadOS 26 the sidebar sometime gets this fake transparency that makes it really hard to quickly grok. A part of Liquid Glass seems to be to sometimes (but not always) take whatever is in the secondary area (the main big content), blur it, mirror it and then use as the background for the sidebar. This is silly and does not work at all for an app like mine. It maybe looks decent if your background is a photo or similar, but not for an app that manages data. Not all views cause the sidebar to get this ugly unreadable background. In most of the cases the sidebar keeps its normal opaque background that it has always had. See this example for how it looks when it's really bad: This is how it should look. Notice that the content of the "main view" is pretty similar to the case where it gets the ugly background. The difference is the segmented thing at the top, ie. a different "root view". Is there some good way for me to force the sidebar to always have an opaque background? I guess I could make a ZStack and put a solid color as the background behind the sidebar, but those kinds of hacks are better to avoid. This can not be how some UI designer envisioned that apps should look? Maybe I'm missing some new modifier or setting somewhere that would led me opt out from this aspect of Liquid Glass? Apart from this it looks pretty nice. There are some bugs where the contents of the main area gets clipped when the sidebar is shown, hidden and then shown again, but that's for another time (and it's surely known already (if the bug tracking system allowed me to search I could verify)). So, any way to make my app look nice again?
4
0
129
3w
[iOS 26] Can no longer detect whether iPhone has notch
I'm currently using the extension below to determine whether an iPhone has a notch so I can adjust my UI accordingly. extension UIDevice { var hasNotch: Bool { if userInterfaceIdiom == .phone, let window = (UIApplication.shared.connectedScenes .compactMap { $0 as? UIWindowScene } .flatMap { $0.windows } .first { $0.isKeyWindow }) { return window.safeAreaInsets.bottom > 0 } return false } } (Adapted from https://stackoverflow.com/questions/73946911/how-to-detect-users-device-has-dynamic-island-in-uikit) This no longer works in iOS 26, and I have yet to find a similar method that works. Does anyone have any fixes?
4
0
147
4w
Webview In-App Browser Microsoft Login Redirection Not Working
Hello, We received a rejection on one of our IOS applications because we were doing Microsoft MSAL login through the user's browser. The representative recommended that we use Webview to do in-app logins. However when we tried to handle the custom app uri redirection (looking like myapp://auth/), Webview does not seem to send the user back to the application. Does anyone have a fix for this? Thanks!
0
0
248
Sep ’25
Automatic menu translation ok with El Capitan, notok with Mojave
Hi everybody, I use a very old photo software called Snapseed v 1.2.1 on 2 MacBook, one runs with El Capitan and the second runs with Mojave. These app has no language selection during install, and no preferences language choice in menu when running. When I execute app on El Capitan, all menus and topics are translate in French, but on Mojave no translation is done. I looked Contents of app and found differents languages files (structured as xx.po where xx=country) located in Resources folder. I deduced translation was executed after getting language param. I checked values on both systems and there are same (LANG=fr_FR.UTF-8). So I tried to change Info.plist file to force code langage to 'fr' in CFBundleLocalizations key. Result is same. Does somebody has a idea of reason of issue and how to solve it ? Snapseed release was 2012, El Capitan 2015 and Mojave 2018, it seems framework used to code app runs differently and can't get language value.
2
0
63
Sep ’25
NSRulerView's background color and transparency (macOS 26)
When I compiled my legacy project with Tahoe's macOS 26 SDK, NSRulerViews are showing a very different design: Under prior macOS versions the horizontal and verrical ruler's background were blurring the content view, which was extending under the rulers, showing through their transparency. With Tahoe the horizontal ruler is always reflecting the scrollview's background color, showing the blurred content view beneath. And the vertical ruler is always completely transparent (without any blurring), showing the content together with the ruler's markers and ticks. It's difficult to describe, I'll try to replicate this behavior with a minimal test project, and probably file a bug report / enhancement request. But before I take next steps, can anyone confirm this observation? Maybe it is an intentional design decision by Apple?
3
0
144
Sep ’25
iOS 26 Liquid Glass not showing
I’m not seeing Liquid Glass on any standard components. A month ago around July 17th I ran our app and saw Liquid Glass on our tab view and various standard components. Those components have not been changed and yet I’m no longer seeing Liquid Glass in our app at all. Components that were previously liquid glass but now are not include TabView and back navigation buttons. I set the UIDesignRequiresCompatibility key explicitly to false but no luck. I was seeing this in Beta 7 and Beta 8 on a real device and on a sim.
2
1
235
Sep ’25
Compositional Layout's broken `visibleItemsInvalidationHandler`
Hello everybody! TLDR: Issues with visibleItemsInvalidationHandler. Minimal code to reproduce available. I've been working with Compositional Layout for a while now and recently I've found myself needing to implement custom animation based on scroll position of UI elements. Once I found visibleItemsInvalidationHandler it felt like the exact solution that I needed. Once I implement I've found out it doesn't quite behave as you'd expect. To put it simply, it seems like the animations only work if your whole layout does not use .estimated nor .uniformAcrossSiblings. As soon as you use them then the animations will stop working, I've debugged it deeper and it seems like the invalidation context generated by it does not include the indexPath of the cells, which is always included in the version in which it works. Feel free to swap the line 51 with its comment to flip between the working and failing version of it. Playground Example My final question therefore is... Is this the expected behavior? The documentation doesn't give any clues about such behavior and although I've tried relentlessly to find a workaround for this specific hiccup I was not successful with it.
1
0
128
Aug ’25
Avoid trackpad gesture conflict between dragging and accessibility zooming when using three fingers
Double-tap three fingers and drag to change zoom” should suppress “Three Finger to Drag”. Currently these gestures are triggered simultaneously, for no real reasons. I saw different behaviors for different environments, but none is desired. Current and desired behavior: This seems an issue so I filed a feedback.
0
0
713
Aug ’25
iPadOS Floating Tab Bar Items (unselected) use Black Text - Unreadable with App Black Background (Dark Mode): UIKit App
Reference Feedback FB19152594 Occurs with my 3rd Party UIKit App called "Lifeorities". Latest occurrence was 7/27/25 at 13:49 pm. Launch app (actual device running iPadOS 26 or iPadOS 26 simulator) Initial screen displays view content and floating tab bar at top of screen (both portrait orientation and landscape). Floating tab bar items respond to liquid glass effect (but liquid glass appearance of the whole tab bar doesn't comply with new glass pill shaped tab bar area). Selected tab bar item obeys selected app designated color (assets). Unselected tab bar items are using black text which is unreadable on app background which used dark mode as default (as intended). Selecting another tab bar item shows the liquid glass effect as you navigate to the new tab bar item and shows the app designated color (assets). Previous tab bar item that was selected, now is unselected and shows black text. NOTE: iOS tab bar items work fine (show white foreground color as desired for unselected tab bar items).
0
1
99
Aug ’25
UITabBar hitTest method is not triggered when click button that is a subview of UITabBar and the subview frame is beyond UITabBar when using Xcode26 build app on OS 26
In our project, we defined a CustomTabBar that inherits UITabBar, and we add some subviews and these subviews' frame is beyond UITabBar, see below picture(a beyond area button, this button is a subview of UITabBar, but frame is out of UITabBar's area): and in order to let this button response to click action, we override the UITabBar's hitTest method, this works well below OS 26 with Xcode version below 26: override public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { let pointInCollectionView = self.beyondAreaButton.convert(point, from: self) if self.beyondAreaButton.bounds.contains(pointInCollectionView) { return self.beyondAreaButton.hitTest(pointInCollectionView, with: event) } return super.hitTest(point, with: event) } but when using Xcode26 build app on OS 26, I noticed the UITabBar is wrapped by a UIKit._UITabBarContainerView and UIKit._UITabBarContainerWrapperView, and it can not trigger the hitTest method. since the hitTest is not triggered, so the button action is no chance to trigger too. Any suggestions to solve this problem, thank you~ And I have file a feedback assistant: FB19252973
1
0
144
Jul ’25
Layout Engine Crash on iOS 26: NSInternalInconsistencyException
Starting with iOS 26 beta, I'm encountering an intermittent crash in production builds related to Auto Layout and background threading. This crash did not occur on iOS 18 or earlier and has become reproducible only on devices running iOS 26 betas. We have already performed a thorough audit of our code: • Verified that all UIKit view hierarchy and layout mutations occur on the main thread. • Re-tested with strict logging—confirmed all remaining layout/constraint/view updates are performed on the main thread. • No third-party UI SDKs are used in the relevant flow. Despite that, the crash still occurs and always from a background thread, during internal UIKit layout commits. Fatal Exception: NSInternalInconsistencyException Modifications to the layout engine must not be performed from a background thread after it has been accessed from the main thread. 0 MyApp 0x7adbc8 FIRCLSProcessRecordAllThreads + 172 1 MyApp 0x7adfd4 FIRCLSProcessRecordAllThreads + 1208 2 MyApp 0x7bc4b4 FIRCLSHandler + 56 3 MyApp 0x7bc25c __FIRCLSExceptionRecord_block_invoke + 100 4 libdispatch.dylib 0x1b7cc _dispatch_client_callout + 16 5 libdispatch.dylib 0x118a0 _dispatch_lane_barrier_sync_invoke_and_complete + 56 6 MyApp 0x7bb1f0 FIRCLSExceptionRecord + 224 7 MyApp 0x7bbd1c FIRCLSExceptionRecordNSException + 456 8 MyApp 0x7badf4 FIRCLSTerminateHandler() + 396 9 Intercom 0x86684 IntercomSDK_sentrycrashcm_cppexception_getAPI + 308 10 libc++abi.dylib 0x11bdc std::__terminate(void (*)()) + 16 11 libc++abi.dylib 0x15314 __cxa_get_exception_ptr + 86 12 libc++abi.dylib 0x152bc __cxxabiv1::failed_throw(__cxxabiv1::__cxa_exception*) + 90 13 libobjc.A.dylib 0x3190c objc_exception_throw + 448 14 CoreAutoLayout 0x13a4 -[NSISEngine optimize] + 314 15 CoreAutoLayout 0x1734 -[NSISEngine _optimizeWithoutRebuilding] + 72 16 CoreAutoLayout 0x1404 -[NSISEngine optimize] + 96 17 CoreAutoLayout 0xee8 -[NSISEngine performPendingChangeNotifications] + 104 18 UIKitCore 0x27ac8 -[UIView(Hierarchy) layoutSubviews] + 136 19 UIKitCore 0xfe760 -[UIWindow layoutSubviews] + 68 20 UIKitCore 0x234228 -[UITextEffectsWindow layoutSubviews] + 44 21 UIKitCore 0x27674 -[UIImageView animationImages] + 912 22 UIKitCore 0x28134 -[UIView(Internal) _viewControllerToNotifyOnLayoutSubviews] + 40 23 UIKitCore 0x18c2898 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2532 24 QuartzCore 0xabd98 CA::Layer::perform_update_(CA::Layer*, CALayer*, unsigned int, CA::Transaction*) + 116 25 QuartzCore 0x8e810 CA::Layer::update_if_needed(CA::Transaction*, unsigned int, unsigned int) + 600 26 QuartzCore 0xad45c CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 200 27 QuartzCore 0x6e30c CA::Context::commit_transaction(CA::Transaction*, double, double*) + 540 28 QuartzCore 0x9afc4 CA::Transaction::commit() + 644 29 QuartzCore 0x16974c CA::Transaction::release_thread(void*) + 180 30 libsystem_pthread.dylib 0x4c28 _pthread_tsd_cleanup + 620 31 libsystem_pthread.dylib 0x4998 _pthread_exit + 84 32 libsystem_pthread.dylib 0x5e3c pthread_atfork + 54 33 libsystem_pthread.dylib 0x1440 _pthread_wqthread + 428 34 libsystem_pthread.dylib 0x8c0 start_wqthread + 8 Any ideas?
4
3
502
Jul ’25
Clarification on Using Secure UITextField to Prevent Screen Capture
Hello Developer Forums Team, I’ve seen that some banking apps prevent screenshots on certain sensitive screens. I’m working on a similar feature in my SDK and want to confirm if my implementation complies with App Store guidelines. Since there’s no public API to block screenshots, I’m using a workaround based on the secure rendering behavior of UITextField (isSecureTextEntry = true). I embed my custom content (e.g., a UITableView) inside the internal secure container of a UITextField, which results in blank content being captured during screenshots—similar to what some banking apps do. Approach Summary I create a UITextField I detect its internal secure container by matching UIKit internal class names as strings I embed my real UI content into that container I do not use or call any private APIs, just match view class names via strings. ScreenshotPreventingView.swift final class ScreenshotPreventingView: UIView { private let textField = UITextField() private let recognizer = HiddenContainerRecognizer() private var contentView: UIView? public var preventScreenCapture = true { didSet { textField.isSecureTextEntry = preventScreenCapture } } public init(contentView: UIView? = nil) { super.init(frame: .zero) self.contentView = contentView setupUI() } private func setupUI() { guard let container = try? recognizer.getHiddenContainer(from: textField) else { return } addSubview(container) NSLayoutConstraint.activate([ container.topAnchor.constraint(equalTo: topAnchor), container.bottomAnchor.constraint(equalTo: bottomAnchor), container.leadingAnchor.constraint(equalTo: leadingAnchor), container.trailingAnchor.constraint(equalTo: trailingAnchor) ]) if let contentView = contentView { setup(contentView: contentView, in: container) } DispatchQueue.main.async { self.preventScreenCapture = true } } private func setup(contentView: UIView) { self.contentView?.removeFromSuperview() self.contentView = contentView guard let container = hiddenContentContainer else { return } container.addSubview(contentView) container.isUserInteractionEnabled = isUserInteractionEnabled contentView.translatesAutoresizingMaskIntoConstraints = false let bottomConstraint = contentView.bottomAnchor.constraint(equalTo: container.bottomAnchor) bottomConstraint.priority = .required - 1 NSLayoutConstraint.activate([ contentView.leadingAnchor.constraint(equalTo: container.leadingAnchor), contentView.trailingAnchor.constraint(equalTo: container.trailingAnchor), contentView.topAnchor.constraint(equalTo: container.topAnchor), bottomConstraint ]) } } HiddenContainerRecognizer.swift struct HiddenContainerRecognizer { private enum Error: Swift.Error { case unsupportedOSVersion(version: Float) case desiredContainerNotFound(_ containerName: String) } func getHiddenContainer(from view: UIView) throws -> UIView { let containerName = try getHiddenContainerTypeInStringRepresentation() let containers = view.subviews.filter { subview in type(of: subview).description() == containerName } guard let container = containers.first else { throw Error.desiredContainerNotFound(containerName) } return container } private func getHiddenContainerTypeInStringRepresentation() throws -> String { if #available(iOS 15, *) { return "_UITextLayoutCanvasView" } if #available(iOS 14, *) { return "_UITextFieldCanvasView" } if #available(iOS 13, *) { return "_UITextFieldCanvasView" } if #available(iOS 12, *) { return "_UITextFieldContentView" } let currentIOSVersion = (UIDevice.current.systemVersion as NSString).floatValue throw Error.unsupportedOSVersion(version: currentIOSVersion) } } How I use it in my Screen let container = ScreenshotPreventingView() override func viewDidLoad() { super.viewDidLoad() container.preventScreenCapture = true container.setup(contentView: viewContainer) //viewContainer is UIView in storyboard, in which all other UI elements are placed in e.g. UITableView self.view.addSubview(container) container.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ container.topAnchor.constraint(equalTo: self.view.topAnchor), container.bottomAnchor.constraint(equalTo: self.view.bottomAnchor), container.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), container.trailingAnchor.constraint(equalTo: self.view.trailingAnchor) ]) } What I’d Like to Confirm Is this approach acceptable for App Store submission? Is there a more Apple-recommended approach to prevent screen capture of arbitrary UI? Thank you for your help in ensuring compliance.
1
0
134
Jul ’25
Cursor Misalignment When Selecting List Options – macOS Tahoe 26.0 Developer Beta 2
Since updating my MacBook Air to macOS Tahoe 26.0 Developer Beta 2, I’ve encountered a persistent cursor misalignment issue: When interacting with lists or contextual menus, the cursor’s visual position does not align with what it actually selects. The system registers the cursor slightly above where it appears, causing clicks to select the wrong option or fail to register. As a temporary workaround, I can sometimes position the cursor off-target and press Enter to select, but this is a frustrating and inefficient workaround. The issue persists after a restart and appears across multiple areas of the OS: Right-clicking an app in the Dock to open the contextual menu → cursor highlights an incorrect item relative to its position. In System Settings menus. Even on the Feedback Assistant site when selecting issue categories. Steps to Reproduce: 1️⃣ Update to macOS Tahoe 26.0 Developer Beta 2 on MacBook Air. 2️⃣ Right-click on any open application in the Dock. 3️⃣ Attempt to select an option from the list that appears. 4️⃣ Observe that the cursor highlights or interacts with a different option than where the cursor is visibly located. Notes: Issue is consistent across reboots. Affects workflow and general navigation. Temporary workaround using keyboard navigation is insufficient for productivity. FB Number: FB18531124 If others are seeing this as well, please confirm below so Apple can prioritize investigation.
2
1
135
Jul ’25
UINavigationController retain cycle in iOS 26
Verbatim of a feedback report (FB18431713) I submitted, duplicated here since we can't see each other's feedbacks, and I wanted a centralized place to track the resolution of this as I'm surely not the only one facing this. When building the app using Xcode 26 beta 2 and running it in an iOS 26 simulator, I'm experiencing a retain cycle in the UINavigationController. From the data I saw in Xcode's memory graph debugger, it seems that _UIViewControllerOneToOneTransitionContext is retaining it. I base this on the fact that the line connecting a view controller and _UIViewControllerOneToOneTransitionContext has a "strong" reference, as indicated in Xcode. (However, I'm reporting this as a retain cycle in UINavigationController, as that's what seems to hold onto this transition-context.)
1
0
144
Jun ’25