Explore the various UI frameworks available for building app interfaces. Discuss the use cases for different frameworks, share best practices, and get help with specific framework-related questions.

All subtopics
Posts under UI Frameworks topic

Post

Replies

Boosts

Views

Activity

Force NSDocument save panel to select most specific type in format popup button
My app supports different plain text file formats, including the standard .txt and Markdown. When creating a new document, my app already asks which format it should have, so when saving it, I would expect that the save panel already selects that format in the popup button, but currently it always selects "Plain Text". For example, I would expect for a Markdown document that it selects "Markdown" instead of "Plain Text". Is there a way to force it to select the most specific format matching the document format?
Topic: UI Frameworks SubTopic: AppKit Tags:
6
1
162
Jul ’25
Screenshot preventing
I’d like to know if Apple currently supports any public API or entitlement for blocking in-app screenshots on iOS. If no such API exists, what is the officially recommended approach for App Store apps to prevent or react to screenshots of sensitive content in a banking app? I have tried using a hidden UITextField with isSecureTextEntry = true and observing UIApplication.userDidTakeScreenshotNotification, but these methods do not block the initial screenshot. Could you please advise how to block screenshots in my app?
Topic: UI Frameworks SubTopic: UIKit
6
0
153
Jun ’25
Change tint of back button in UINavigationItem on iOS 26
I am struggling to change the tint of the back button in an UINavigationItem. In iOS 18.6 it looks like this while on iOS 26 the same looks like this I can live without the Dictionary but I'd like to get the blue color back. In viewDidLoad() I have tried navigationItem.backBarButtonItem?.tintColor = .link but this did not work since navigationItem.backBarButtonItem is nil. My second attempt was navigationController?.navigationBar.tintColor = .link but this didn't work either. I have even set the Global Tint to Link Color but this had no effect either. Does anyone have an idea how to change the tint of the back button in an UINavigationItem on iOS 26?
Topic: UI Frameworks SubTopic: UIKit Tags:
6
1
365
1w
SwiftUI @State Updates Not Reflecting in UI Until View Reconstruction (Xcode Preview & Device)
Issue Description I'm experiencing a bizarre SwiftUI state update issue that only occurs in Xcode development environment (both Canvas preview and device debugging), but does not occur in production builds downloaded from App Store. Symptom: User taps a button that modifies a @State variable inside a .sheet Console logs confirm the state HAS changed But the UI does not update to reflect the new state Switching to another file in Xcode and back to ContentView instantly fixes the issue The production build (same code) works perfectly fine Environment Xcode: 16F6 (17C52) iOS: 26.2 (testing on iPhone 13) macOS: 25.1.0 (Sequoia) SwiftUI Target: iOS 15.6+ Issue: Present in both Xcode Canvas and on-device debugging Production: Same code works correctly in App Store build (version 1.3.2) Code Structure Parent View (ContentView.swift) struct ContentView: View { @State private var selectedSound: SoundTheme = .none @State private var showSoundSheet = false var body: some View { VStack { // Display button shows current selection SettingButton( title: "Background Sound", value: getLocalizedSoundName(selectedSound) // ← Not updating ) { showSoundSheet = true } } .sheet(isPresented: $showSoundSheet) { soundSelectionView } } private var soundSelectionView: some View { ForEach(SoundTheme.allCases) { sound in Button { selectedSound = sound // ← State DOES change (confirmed in console) // Audio starts playing correctly audioManager.startAmbientSound(sound) } label: { Text(sound.name) } } } private func getLocalizedSoundName(_ sound: SoundTheme) -> String { // Returns localized name return sound.localizedName }} What I've Tried Attempt 1: Adding .id() modifier SettingButton(...) .id(selectedSound) // Force re-render when state changes Result: No effect Attempt 2: Moving state modification outside withAnimation // Before (had animation wrapper):withAnimation { selectedSound = sound}// After (removed animation):selectedSound = sound Result: No effect Attempt 3: Adding debug print() statements selectedSound = soundprint("State changed: (selectedSound)") // ← Adding this line FIXES the issue! Result: Mysteriously fixes the issue! But removing print() breaks it again. This suggests a timing/synchronization issue in Xcode's preview system. Observations What works: ✅ Console logs confirm state changes correctly ✅ Switching files in Xcode triggers view reconstruction → everything works ✅ Production build from App Store works perfectly ✅ Adding print() statements "fixes" it (likely changes execution timing) What doesn't work: ❌ Initial file load in Xcode ❌ Hot reload / incremental updates ❌ Both Canvas preview and on-device debugging Workaround that works: Click another file in Xcode Click back to ContentView.swift Everything works normally Key Question Is this a known issue with Xcode 16's SwiftUI preview/hot reload system? The fact that: Same exact code works in production Adding print() "fixes" it File switching triggers reconstruction that fixes it ...all suggest this is an Xcode tooling issue, not a code bug. However, it makes development extremely difficult as I can't reliably test changes without constantly switching files or killing the app. What I'm Looking For Confirmation: Is this a known Xcode 16 issue? Workaround: Any better solution than constantly switching files? Root cause: What's causing this state update timing issue? Any insights would be greatly appreciated!
Topic: UI Frameworks SubTopic: SwiftUI
6
0
352
Dec ’25
SwiftUI .destructive alert button in macOS dark mode — poor contrast
Here is a simple view to demonstrate the issue struct ContentView: View { @State private var isPresented = false var body: some View { VStack { Button("Test") { isPresented = true } } .alert("Test", isPresented: $isPresented, actions: { Button("Delete All", role: .destructive) {} }, message: { Text("Are You Sure?") }) .padding() } }``` Which results in ![example alert]("https://developer.apple.com/forums/content/attachment/c6210120-d82e-4df5-a01a-fc5cb168e1bf" "title=Screenshot 2025-09-08 at 08.57.21.png;width=546;height=442") The destructive button is almost unreadable. WCAG score is 1.4, far below the minimum recommended 4.5. I found [this post](https://stackoverflow.com/q/66448869) on SO going back to Big Sur, but not on this forum. Any known workarounds (except for building my own dialogs, which I am trying to avoid)? Using confirmationDialog instead of alert does not make a difference.
6
0
144
Sep ’25
Issue with UIActivityViewController Not Showing X (formerly Twitter) and Facebook Icons When Sharing Images on iOS 26 Beta
I have installed the iOS 26 Beta on my device and conducted a comprehensive functionality test of my iOS application, which I designed and developed. The application includes a feature that allows users to share images directly to X (formerly Twitter) and Facebook. During testing, I encountered an issue where the icons for X (formerly Twitter) and Facebook do not appear in the share dialog, despite both apps being installed on the device. This issue prevents users from sharing images to these platforms directly from the app. Steps to Reproduce: 1.Install iOS 26 Beta on a compatible device. 2.Ensure that both the X (formerly Twitter) and Facebook apps are installed and logged in on the device. 3.Open the iOS application and navigate to the image sharing feature. 4.Attempt to share an image using the share dialog. 5.Observe that the icons for X (formerly Twitter) and Facebook are missing from the share options. Expected Behavior: The share dialog should display icons for X (formerly Twitter) and Facebook, allowing users to share images directly to these platforms. Actual Behavior: The icons for X (formerly Twitter) and Facebook do not appear in the share dialog, preventing direct sharing to these platforms. Code Implementation: I have not implemented any code to exclude X (formerly Twitter) and Facebook from the share options. Below is the relevant code for controlling the share screen: let activityViewController = UIActivityViewController(activityItems: activityItems, applicationActivities: applicationActivities) let excludedTypes = [ UIActivity.ActivityType.assignToContact, UIActivity.ActivityType.print, ] activityViewController.excludedActivityTypes = excludedTypes activityViewController.completionWithItemsHandler = completion self.present(activityViewController, animated: true, completion: nil) As shown in the implementation, there is no exclusion of X (formerly Twitter) and Facebook, yet their icons do not appear in the share dialog.
6
4
614
Sep ’25
perspectiveTransform causing large memory spike / app being killed
I have a PDF which contains geocoordinates. I'm extracting out that image with the following code (this is for an iOS application): guard let cgDocument = CGPDFDocument(overlay.pdfUrl as CFURL) else { return } guard let cgPage = cgDocument.page(at: 1) else { return } var boundingRect = self.rect(for: overlay.boundingMapRect) let pdfPageRect = cgPage.getBoxRect(.mediaBox) let renderer = UIGraphicsImageRenderer(size: pdfPageRect.size) var img = renderer.image { ctx in UIColor.white.set() ctx.fill(pdfPageRect) ctx.cgContext.translateBy(x: 0.0, y: pdfPageRect.size.height) ctx.cgContext.scaleBy(x: 1.0, y: -1.0) ctx.cgContext.drawPDFPage(cgPage) } Once I have that image, I then need to adjust it to fit the specific coordinate corners. For that, I'm doing the following using a perspectiveTransform: let ciImg = CIImage(image: img)! let perspectiveTransformFilter = CIFilter.perspectiveTransform() perspectiveTransformFilter.inputImage = ciImg perspectiveTransformFilter.topRight = cartesianForPoint(point: ur, extent: boundingRect) perspectiveTransformFilter.topLeft = cartesianForPoint(point: ul, extent: boundingRect) perspectiveTransformFilter.bottomRight = cartesianForPoint(point: lr, extent: boundingRect) perspectiveTransformFilter.bottomLeft = cartesianForPoint(point: ll, extent: boundingRect) let txImg = perspectiveTransformFilter.outputImage! img = UIImage(ciImage: txImg) The original image is 792 x 612 (a landscape PDF) but the boundingRect covering the coordinates is 25625 x 20030. Obviously when I try to draw the image into that bounding box the app runs out of memory (25625 x 20030 x 4 is around 2GB of memory). What I'm struggling with is - how do I correctly scale this image to fit into the bounding box even though the bounding box is, oh, 10x the resolution of the actual device? There's some key CoreGraphics thing I'm sure I'm missing here.
6
0
258
Sep ’25
SwiftData document based on iOS18 shows blank screen
I have some apps using SwiftData document based. They work as expected under iOS17, but not under iOS18: install the app on a iPad 11 pro (first gen) from my MacBook open the app and open an existing fils (perfect under iOS17) it shows a blank, white screen, no data I can create a new document, blank screen, no data When I open that newly created file on a iOS 17 iPad pro, it works perfect, as expected The apps were created from scratch under macOS 14.7 with the corresponding Xcode/Swift/UI version. iOS devices under iOS17 Are there any known problems with document based SwiftData-apps under iOS18, are there any changes one has to made? Thank You so much for any help!
6
0
786
Apr ’25
TextKit 2 calls NSTextLayoutFragment's draw method too often
The following is verbatim of a feedback report (FB19809442) I submitted, shared here as someone else might be interested to see it (I hate the fact that we can't see each other's feedbacks). On iOS 16, TextKit 2 calls NSTextLayoutFragment's draw(at:in:) method once for the first paragraph, but for every other paragraph, it calls it continuously on every scroll step in the UITextView. (The first paragraph is not cached; its draw is called again when it is about to be displayed again, but then it is again called only once per its lifecycle.) On iOS 17, the behavior is similar; the draw method gets called once for the 1st and 2nd paragraph, and for every other paragraph it again gets called continuously as a user scrolls a UITextView. On iOS 18 (and iOS 26 beta 4), TextKit 2 calls the layout fragment's draw(at:in:) on every scroll step in the UITextView, for all paragraphs. This results in terrible performance. TextKit 2 is promised to bring many performance benefits by utilizing the viewport - a new concept that represents the visible area of a text view, along with a small overscroll. However, having the draw method being constantly called almost negates all the performance benefits that viewport brings. Imagine what could happen if someone needs to add just a bit of logic to that draw method. FPS drops significantly and UX is terribly degraded. I tried optimizing this by only rendering those text line fragments which are in the viewport, by using NSTextViewportLayoutController.viewportBounds and converting NSTextLineFragment.typographicBounds to the viewport-relative coordinate space (i.e. the coordinate space of the UITextView itself). However, this patch only works on iOS 18 where the draw method is called too many times, as the viewport changes. (I may have some other problems in my implementation, but I gave up on improving those, as this can't work reliably on all OS versions since the underlying framework isn't calling the method consistently.) Is this expected? What are our options for improving performance in these areas?
6
0
242
Aug ’25
Should SwiftUI view models in Swift 6 be both @Observable and @MainActor?
Hi, In the WWDC25 session Elevate an app with Swift concurrency (timestamps: 8:04 and later), the StickerViewModel is shown annotated with @Observable but not @MainActor. The narration mentions that updates happen on the main thread, but that guarantee is left implicit in the calling code. In Swift 6, though, one of the major benefits is stronger compiler enforcement against data races and isolation rules. If a view model were also annotated with @MainActor, then the compiler could enforce that observable state is only updated on the main actor, preventing accidental background mutations or updates that can cause data races between nonisolated and main actor-isolated uses. Since @Observable already signals that state changes are intended to be observed (and in practice, usually by views), it seems natural that such types should also be main-actor isolated. Otherwise, we’re left with an implicit expectation that updates will always come from the main thread, but without the compiler’s help in enforcing that rule. This also ties into the concept of local reasoning that was emphasized in other Swift 6 talks (e.g. Beyond the basics of structured concurrency). With @MainActor, I can look at a view model and immediately know that all of its state is main-actor isolated. With only @Observable, that guarantee is left out, which feels like it weakens the clarity that Swift 6 is trying to promote. Would it be considered a best practice in Swift 6 to use both @Observable and @MainActor for UI-facing view models? Or is the intention that SwiftUI developers should rely on calling context to ensure main-thread updates, even if that means the compiler cannot enforce isolation? Thanks!
6
0
291
Aug ’25
UITabBar Appears During Swipe-Back Gesture on iOS 26 Liquid Glass UI
Hello, While integrating the Liquid Glass UI introduced in iOS 26 into my existing app, I encountered an unexpected issue. My app uses a UITabBarController, where each tab contains a UINavigationController, and the actual content resides in each UIViewController. Typically, I perform navigation using navigationController?.pushViewController(...) and hide the TabBar by setting vc.hidesBottomBarWhenPushed = true when needed. This structure worked perfectly fine prior to iOS 26, and I believe many apps use a similar approach. However, after enabling Liquid Glass UI, a problem occurs. Problem Description From AViewController, I push BViewController with hidesBottomBarWhenPushed = true. BViewController appears, and the TabBar is hidden as expected. When performing a swipe-back gesture, as soon as AViewController becomes visible, the TabBar immediately reappears (likely due to A’s viewWillAppear). The TabBar remains visible for a short moment even if the gesture is canceled — during that time, it is also interactable. Before iOS 26, the TabBar appeared synchronized with AViewController and did not prematurely show during the swipe transition. Tried using the new iOS 18 API: tabBarController?.setTabBarHidden(false, animated: true) It slightly improves the animation behavior, but the issue persists. If hidesBottomBarWhenPushed is now deprecated or discouraged, migrating entirely to setTabBarHidden would require significant refactoring, which is not practical for many existing apps. Is this caused by a misuse of hidesBottomBarWhenPushed, or could this be a regression or design change in iOS 26’s Liquid Glass UI?
Topic: UI Frameworks SubTopic: UIKit Tags:
6
3
874
Dec ’25
UIDocumentPickerViewController does not allow picking folders on connected servers on iOS26
Hey there, I have an app that allows picking any folder via UIDocumentPickerViewController. Up until iOS18 users were able to pick folders from connected servers (servers connected in the Files app) as well. On iOS26, the picker allows for browsing into the connected servers, but the Select button is greyed out and does nothing when tapped. Is this a known issue? This breaks the whole premise of my file syncronization application.
6
0
251
Nov ’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?
6
0
342
Nov ’25
Can I tell when my iOS Widget is running on MacOS (when Use IPhone Widgets is on)
I have an iOS Widget that also can load on the Mac when the Use iPhone Widgets setting is turned on on the Mac in Desktop & Dock. I want to use a different url scheme to open video clips from the widget if it is being clicked on iOS or the Mac. I tried using ProcessInfo.processInfo.isiOSAppOnMac but it always thinks it is on iOS. I also tried looking for the user document path to see if it was /var/mobile/ or /Users/. but it always thinks it is /var/mobile. I assume this is as it is not really a catalyst app but a WidgetKit extension from the phone. Is there anyway I can figure out when the widget is running on the mac? Thanks!
6
0
628
Jun ’25
Issues with List selection in Sequoia (SwiftUI)
In one of my applications I use several List views with Sections. After upgrading to Sequoia I faced the issue, that after selecting an item, the List suddenly scrolls to a different position. Sometimes the selection even gets out of the view, but in every case a double click just went to the wrong item. At one list I found out, that the issue could be solved after changing the data source. I used a computed property, what seems to be a stupid idea. After changing this it now works. Unfortunately there is another List, where this didn't bring the solution. And unfortunately, I cannot reproduce the issue in a code example. One guess of mine is, that it could be related to the fact, that the rows have different heights (because in some are two lines of text and in some are three). And it seems to happen only in very long lists. It worked perfectly in Sonoma. Does anyone face the same issue?
Topic: UI Frameworks SubTopic: SwiftUI
6
0
474
Feb ’25
SwiftUI View cannot conform custom Equatable protocol in Swift 6.
In Swift 6, stricter concurrency rules can lead to challenges when making SwiftUI views conform to Equatable. Specifically, the == operator required for Equatable must be nonisolated, which means it cannot access @MainActor-isolated properties. This creates an error when trying to compare views with such properties: Error Example: struct MyView: View, Equatable { let title: String let count: Int static func ==(lhs: MyView, rhs: MyView) -> Bool { // Accessing `title` here would trigger an error due to actor isolation. return lhs.count == rhs.count } var body: some View { Text(title) } } Error Message: Main actor-isolated operator function '==' cannot be used to satisfy nonisolated protocol requirement; this is an error in the Swift 6 language mode. Any suggestions? Thanks FB: FB15753655 (SwiftUI View cannot conform custom Equatable protocol in Swift 6.)
6
0
997
Mar ’25
iOS 26 regression: Slider does not respect step parameter
In iOS 26, the Slider control no longer respects the step parameter. For example, import SwiftUI struct ContentView: View { @State private var sliderValue: CGFloat = 16 var body: some View { Slider( value: $sliderValue, in: 0...100, step: 5, onEditingChanged: { editing in print(sliderValue) } ) } } In iOS 18, this prints values like 5, 35, 60, 95, etc. In iOS 26.0 (release version), this prints floats that are not rounded to the nearest 5, and the slider does not snap to values ending in 5. Feedback report number: FB20320542
Topic: UI Frameworks SubTopic: SwiftUI
6
4
343
Nov ’25