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

Created

tvOS 26.2 Homescreen Shadow Glitch
Hi @DTS Engineer in tvOS 26.2 Beta is still this annoying Shadow Glitch… I have submitted an Bug-Report, but dont get an Answer… FB20049524 The Animation is not smooth and the Shadow is abruptly „jumping“… I don’t get any Response from the Apple Engineers. But this GUI Glitch makes the otherwise very high-quality tvOS GUI appear very unprofessional. Could you please help me? 🤔
Topic: UI Frameworks SubTopic: General Tags:
0
0
29
1w
Spotlight Shows "Helper Apps" That Are Inside Main App Bundle That Are Not Intended to Be Launched By The User
I have Mac apps that embed “Helper Apps” inside their main bundle. The helper apps do work on behalf of the main application. The helper app doesn’t show a dock icon, it does show minimal UI like an open panel in certain situations (part of NSService implementation). And it does make use of the NSApplication lifecycle and auto quits after it completes all work. Currently the helper app is inside the main app bundle at: /Contents/Applications/HelperApp.app Prior to Tahoe these were never displayed to user in LaunchPad but now the Spotlight based AppLauncher displays them. What’s the recommended way to get these out of the Spotlight App list on macOS Tahoe? Thanks in advance.
3
0
64
1w
Hide sensitive data on watchOS with WidgetKit
I am looking for a way to hide sensitive information on my Complication, basically whenever the user does not actively look at it. That includes Always-On state Locked State (e.g. Watch not on wrist) I could observe differences in behavior between Preview, Simulator and Real Device. In general it looks like the .privacySensitive() modifier does not do anything for my purpose (except if the user enables redaction in settings). For the always-on state I could use @Environment(\.isLuminanceReduced) to conditionally apply .redacted(reason: .placeholder). This works most of the time. @ViewBuilder func preservePrivacy(_ isLuminanceReduced: Bool) -> some View { if isLuminanceReduced { self .redacted(reason: .placeholder) } else { self } } However I still cannot hide the information when the Watch is locked completely (via PIN-Code). I still believe that .privacySensitive() should take care of it, but apparently it doesn't. So the question is: How can I hide sensitive information when the Watch is locked? This is my widget: Text("1234") .privacySensitive() .preservePrivacy(isLuminanceReduced) .widgetCurvesContent() .widgetLabel { Text("PIN") .widgetAccentable() .foregroundStyle(.secondary) } .containerBackground(.teal.gradient, for: .widget) (I included the whole story, because possibly my whole approach is wrong.)
1
0
48
1w
Scrolling through long lists with ScrollView and LazyVstack
What is the correct way to implement scrolling in a looong list that uses ScrollView and LazyVstack Imagine I have some api that returns a longs list of comments with replies The basic usecase is to scroll to the bottom(to the last comment) Most of the time this works fine But, imagine some of the comments have many replies like 35 or more (or even 300) User expands replies for the first post, then presses scroll to bottom. The scrollbar reaches the bottom and I see the blank screen. Sometimes the scrollbar may jump for a while before lazyvstack finishes loading or until I manually scroll up a bit or all the way up and down What should I do in this case? Is this the swiftui performance problem that has no cure? Abstract example: ScrollViewReader { proxy in ScrollView { LazyVStack { ForEach(comments) { comment in CommentView(comment: comment) .id("comment-\(comment.id)") } } } } struct CommentView: View { let comment: Comment @State var isExpanded = false var body: some View { VStack { Text(comment.text) if isExpanded { RepliesView(replies: comment.replies) // 35-300+ replies } } } } ... scroll proxy.scrollTo("comment-\(lastComment.id)", anchor: .bottom)
3
0
95
1w
SwiftUI WebView Error
I'm using SwiftUI WebView and this error happens when app becomes inactive, the webview changes to blank, and will be in this state all along even if reopen a new webview. When I switch back to WKWebview, everything works fine. environment Xcode 26.1(17B55) on macOS 15.7.1 Error acquiring assertion: <Error Domain=RBSServiceErrorDomain Code=1 "((target is not running or doesn't have entitlement com.apple.developer.web-browser-engine.rendering AND target is not running or doesn't have entitlement com.apple.developer.web-browser-engine.networking AND target is not running or doesn't have entitlement com.apple.developer.web-browser-engine.webcontent))" UserInfo={NSLocalizedFailureReason=((target is not running or doesn't have entitlement com.apple.developer.web-browser-engine.rendering AND target is not running or doesn't have entitlement com.apple.developer.web-browser-engine.networking AND target is not running or doesn't have entitlement com.apple.developer.web-browser-engine.webcontent))}> this is the code, pretty simple, in load() function i just call page.load(). WebView(vm.page) .onAppear { Task { await vm.load() } }
0
0
71
1w
when UIAlertController dismisses app hangup
Before iOS 26.1 our app work fine. but, when some users update to iOS 26.1 our app has very strange issues. Our app has a feature to upload pictures to server, before update pictures we will popup a UIAlertController to let user choose, there are 3 options, album, take a photo, cloud, or cancel. when click option button UIAlertController is hangup here not any response, and Xcode has no useful logs. How can I fix it? This app is work online for 8 years!!
Topic: UI Frameworks SubTopic: UIKit
2
0
29
1w
The floating keyboard on iPad OS 26 is not displaying
On iPad OS 26, the custom keyboard works correctly with a full keyboard, but with a floating keyboard, there is only one line and the console displays a constraint error. 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. ( "<NSLayoutConstraint:0x600002172c10 V:|-(10)-[TUIKeyboardContentView:0x1039c5410] (active, names: '|':TUIKeyplaneView:0x1039c3e20 )>", "<NSLayoutConstraint:0x600002172c60 V:[TUIKeyboardContentView:0x1039c5410]-(-11)-| (active, names: '|':TUIKeyplaneView:0x1039c3e20 )>", "<NSLayoutConstraint:0x6000021721c0 V:|-(0)-[TUIKeyplaneView:0x1039c3e20] (active, names: UIKeyboardLayoutStar Prev...:0x105160e00, '|':UIKeyboardLayoutStar Prev...:0x105160e00 )>", "<NSLayoutConstraint:0x600002172210 V:[TUIKeyplaneView:0x1039c3e20]-(0)-| (active, names: UIKeyboardLayoutStar Prev...:0x105160e00, '|':UIKeyboardLayoutStar Prev...:0x105160e00 )>", "<NSLayoutConstraint:0x6000021728a0 V:|-(0)-[UIKeyboardLayoutStar Prev...] (active, names: UIKeyboardLayoutStar Prev...:0x105160e00, '|':UIKeyboardImpl:0x109905fa0 )>", "<NSLayoutConstraint:0x6000021728f0 V:[UIKeyboardLayoutStar Prev...]-(0)-| (active, names: UIKeyboardLayoutStar Prev...:0x105160e00, '|':UIKeyboardImpl:0x109905fa0 )>", "<NSLayoutConstraint:0x600002177980 '_UITemporaryLayoutHeight' UIKeyboardImpl:0x109905fa0.height == 0 (active)>", "<NSLayoutConstraint:0x600002172df0 'TUIKeyplane.height' TUIKeyboardContentView:0x1039c5410.height == 217 (active)>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x600002172df0 'TUIKeyplane.height' TUIKeyboardContentView:0x1039c5410.height == 217 (active)> 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. iPad OS 26 custom keyboard, full keyboard mode is working normally.
Topic: UI Frameworks SubTopic: UIKit
0
0
54
1w
UIViewRepresentable Coordinator @Binding returns stale value when accessed via context.coordinator but fresh value when accessed via self
I'm encountering unexpected behavior with @Binding in a UIViewRepresentable's Coordinator. The same Coordinator instance returns different values depending on how the property is accessed. Environment: iOS 17+ / Xcode 15+ SwiftUI with UIViewRepresentable Issue: When I access @Binding var test inside the Coordinator: ✅ Via self.test in Coordinator methods: Returns the updated value ❌ Via context.coordinator.test in updateUIView: Returns the stale/initial value Both access the same Coordinator instance (verified by memory address), yet return different values. Minimal Reproducible Example: struct ContentView: View { @State private var test: [Int] = [1, 2, 3, 4, 5] var body: some View { VStack { TestRepresentable(test: $test) Text("State: \(test.description)") } } } struct TestRepresentable: UIViewRepresentable { @Binding var test: [Int] func makeUIView(context: Context) -> UIButton { let button = UIButton(type: .system) button.setTitle("Toggle", for: .normal) button.addTarget( context.coordinator, action: #selector(Coordinator.buttonTapped), for: .touchUpInside ) return button } func updateUIView(_ uiView: UIButton, context: Context) { // Log coordinator instance address let coordAddr = String(describing: Unmanaged.passUnretained(context.coordinator).toOpaque()) print("[updateUIView] Coordinator address: \(coordAddr)") // Log values print("[updateUIView] self.test: \(self.test)") print("[updateUIView] context.coordinator.test: \(context.coordinator.test)") // These should be the same but they're not! // self.test shows updated value // context.coordinator.test shows stale value } func makeCoordinator() -> Coordinator { Coordinator(test: $test) } class Coordinator: NSObject { @Binding var test: [Int] var idx: Int = 0 init(test: Binding<[Int]>) { _test = test } @objc func buttonTapped() { idx += 1 if idx < test.count { test[idx] += 5 } // Log coordinator instance address let selfAddr = String(describing: Unmanaged.passUnretained(self).toOpaque()) print("[buttonTapped] Coordinator address: \(selfAddr)") // Log value - this shows the UPDATED value print("[buttonTapped] self.test: \(test)") } } } Actual Output: [Initial] [updateUIView] Coordinator address: 0x600001234567 [updateUIView] self.test: [1, 2, 3, 4, 5] [updateUIView] context.coordinator.test: [1, 2, 3, 4, 5] [After first tap] [buttonTapped] Coordinator address: 0x600001234567 [buttonTapped] self.test: [1, 7, 3, 4, 5] ✅ Updated! [updateUIView] Coordinator address: 0x600001234567 ← Same instance [updateUIView] self.test: [1, 7, 3, 4, 5] ✅ Updated! [updateUIView] context.coordinator.test: [1, 2, 3, 4, 5] ❌ Stale! [After second tap] [buttonTapped] Coordinator address: 0x600001234567 [buttonTapped] self.test: [1, 7, 8, 4, 5] ✅ Updated! [updateUIView] Coordinator address: 0x600001234567 ← Same instance [updateUIView] self.test: [1, 7, 8, 4, 5] ✅ Updated! [updateUIView] context.coordinator.test: [1, 2, 3, 4, 5] ❌ Still stale! Questions: Why does context.coordinator.test return a stale value when it's the same Coordinator instance? Is this intended behavior or a bug? What's the correct pattern to access Coordinator's @Binding properties in updateUIView? Workaround Found: Using self.test instead of context.coordinator.test in updateUIView works, but I'd like to understand why accessing the same property through context yields different results. Related: I've seen suggestions to update coordinator.parent = self in updateUIView, but this doesn't explain why the same object's property returns different values. Binding documentation states it's "a pair of get and set closures," but there's no explanation of how Context affects closure behavior. Any insights would be greatly appreciated! P.S - https://stackoverflow.com/questions/69552418/why-does-a-binding-in-uiviewrepresentables-coordinator-have-a-constant-read-valu This is the link that I found out online with same problem that I have but not answered well.
0
0
25
1w
Sheet background in share extension ignores Liquid Glass effect in iOS 26/Xcode 26
I’m developing a share extension for iOS 26 with Xcode 26. When the extension’s sheet appears, it always shows a full white background, even though iOS 26 introduces a new “Liquid Glass” effect for partial sheets. Expected: The sheet background should use the iOS 26 glassmorphism effect as seen in full apps. Actual behavior: Custom sheets in my app get the glass effect, but the native system sheet in the share extension always opens as plain white. Steps to reproduce: Create a share extension using UIKit Present any UIViewController as the main view Set modalPresentationStyle = .pageSheet (or leave as default) Observe solid white background, not glassmorphism Sample code: swift override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .clear preferredContentSize = CGSize(width: UIScreen.main.bounds.width, height: 300) } Troubleshooting attempted: Tried adding UIVisualEffectView with system blur/materials Removed all custom backgrounds Set modalPresentationStyle explicitly Questions: Is it possible to enable or force the Liquid Glass effect in share extensions on iOS 26? Is this a limitation by design or a potential bug? Any workaround to make extension sheet backgrounds match system glass appearance?
1
0
51
1w
Sheet background in share extension ignores Liquid Glass effect in iOS 26/Xcode 26
I’m developing a share extension for iOS 26 with Xcode 26. When the extension’s sheet appears, it always shows a full white background, even though iOS 26 introduces a new “Liquid Glass” effect for partial sheets. Expected: The sheet background should use the iOS 26 glassmorphism effect as seen in full apps. Actual behavior: Custom sheets in my app get the glass effect, but the native system sheet in the share extension always opens as plain white. Steps to reproduce: Create a share extension using UIKit Present any UIViewController as the main view Set modalPresentationStyle = .pageSheet (or leave as default) Observe solid white background, not glassmorphism Sample code: swift override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .clear preferredContentSize = CGSize(width: UIScreen.main.bounds.width, height: 300) } Troubleshooting attempted: Tried adding UIVisualEffectView with system blur/materials Removed all custom backgrounds Set modalPresentationStyle explicitly Questions: Is it possible to enable or force the Liquid Glass effect in share extensions on iOS 26? Is this a limitation by design or a potential bug? Any workaround to make extension sheet backgrounds match system glass appearance?
4
0
112
1w
iOS26+ CNContactViewController will duplicate phone numbers and email addresses if an Avatar image is attached when creating the contact
Using the ContactUI framework CNContactViewController(forNewContact contact: CNContact?) to add a new contact to the ContactStore. If the new contact does not have an attached image then the contact is saved correctly. If the new contact DOES have an attached image then all entries in the phoneNumbers or emailAddresses array are doubled when written to the contactStore. Viewing the contact via the Contacts app shows the duplications. This is only happening on iOS26+. Earlier versions of the operating system do not show duplicates. Has anyone else seen this issue? Feedback reference: FB20910502
2
0
187
1w
NSOutlineView incorrectly draws disclosure indicator when item views are SwiftUI views.
I am using an NSOutlineView via NSViewRepresentable in a SwiftUI application running on macOS. Everything has been working fine. Up until lately, I've been returning a custom NSView for each item using the standard: func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? { // View recycling omitted. return MyItemView(item) } Now I want to explore using a little bit more SwiftUI and returning an NSHostingView from this delegate method. func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? { // View recycling omitted. let rootView = MySwiftUIView(item) let hostingView = NSHostingView(rootView: rootView) return hostingView } For the most part, this appears to be working fine. NSOutlineView is even correctly applying highlight styling, so that's great. But there's one small glitch. The outline view's disclosure triangles do not align with the hosting view's content. The disclosure triangles appear to just be pinned to the top. Perhaps they can't find a baseline constraint or something? Is there any SwiftUI modifier or AppKit/SwiftUI technique I can apply here to get the disclosure button to appear in the right place? Here is what the SwiftUI + NSHostingView version looks like: Note the offset disclosure indicators. (Image spacing is a bit off as well using Label, but fixable. Here is what an NSView with NSTextFields looks like: Disclosure indicators are correctly aligned, as you would expect.
1
0
103
1w
UICollectionViewDelegate method not invoked
I’m running the interactive reordering sample from this repo and hitting an odd behavior on newer simulators: the delegate method that lets you steer the drop: func collectionView(_:targetIndexPathForMoveOfItemFromOriginalIndexPath:atCurrentIndexPath:toProposedIndexPath:) works fine on iOS 16, but on iOS 18 and iOS 26 simulators it never fires, so the item always lands at the proposed index path and I can’t constrain moves or adjust the compositional view layout to accommodate the cell of different size. Is this a new behavior in modern iOS? If so, what’s the recommended way to control the final index path for the UICollectionViewDropDelegate now?
Topic: UI Frameworks SubTopic: UIKit Tags:
0
1
31
1w
Tab bar alignment issue from iOS 26
I have a tab bar with 4 tabs. Since iOS 26, I’m facing an issue with the tab alignment — the text automatically shrinks, and the tab icon shifts upward for some tabs. I am using UITab property for creating Tabs from os Version above 18 and UITabBar for os version below 18.
1
1
97
1w
Picking image in iOS-first app when running it on macOS 26
An app that is capable of running on iPad can be usually run on Mac if properly designed and that's great. Recently I've tried to launch one of my old apps on macOS 26 in "Designed for iPad" mode and noticed that image picker behaves oddly. Images are barely selectable, you have to click several times and yet it might select image and might not. On iPhone and on iPad any kind of image picking works fine. I've tried all kinds of native pickers (PhotosPicker, PHPickerViewController, UIImagePickerController), but the result is almost the same. So how should I nowadays do image picking in (mostly) iOS app when it is run on macOS? Below is the most canonical and modern code I've tried. The issue is reproduced even with such bare minimum of code with the label not being put to a Form/List or any other factors. import SwiftUI import PhotosUI struct ContentView: View { @State private var selectedItem: PhotosPickerItem? @State private var selectedImage: UIImage? var body: some View { VStack { if let selectedImage { Image(uiImage: selectedImage) .resizable() .scaledToFit() } // Most modern photo library picker, not `PHPickerViewController`, not `UIImagePickerController` based pickerPhotosPicker( selection: $selectedItem, matching: .images ) { Label("Select Photo", systemImage: "photo") } .onChange(of: selectedItem) { newItem inTask { if let data = try? await newItem?.loadTransferable(type: Data.self), let uiImage = UIImage(data: data) { selectedImage = uiImage } } } } } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
3
0
50
1w
MFMessageComposeViewController: Close button disappears after sending message on iOS 26
Description When presenting MFMessageComposeViewController from SwiftUI using UIViewControllerRepresentable, the close button disappears after sending a message on iOS 26. As a result, the message compose screen cannot be dismissed, leaving the user stuck on the Messages UI. struct MessageComposeView: UIViewControllerRepresentable { typealias Completion = (_ messageSent: Bool) -> Void static var canSendText: Bool { MFMessageComposeViewController.canSendText() } let recipients: [String]? let body: String? let completion: Completion? func makeUIViewController(context: Context) -> UIViewController { guard Self.canSendText else { let errorView = MessagesUnavailableView() return UIHostingController(rootView: errorView) } let controller = MFMessageComposeViewController() controller.messageComposeDelegate = context.coordinator controller.recipients = recipients controller.body = body return controller } func updateUIViewController(_ uiViewController: UIViewController, context: Context) {} func makeCoordinator() -> Coordinator { Coordinator(completion: self.completion) } class Coordinator: NSObject, MFMessageComposeViewControllerDelegate { private let completion: Completion? public init(completion: Completion?) { self.completion = completion } public func messageComposeViewController(_ controller: MFMessageComposeViewController, didFinishWith result: MessageComposeResult) { if result == .cancelled { controller.dismiss(animated: true, completion: nil) } completion?(result == .sent) } } } Before sending message: After sending message:
Topic: UI Frameworks SubTopic: SwiftUI
0
0
11
1w
UITextField selects all text on focus when the content is long — how to keep the caret at the end?
I’m building a custom input field using UITextField. When the user taps to focus the field and the text is long, the entire text becomes selected by default. This is the same behavior you can see in iOS Safari’s search field or the Messages app search field. What I want: when the field becomes first responder, the caret should be placed at the end of the text (latest word), without selecting all the text. Here’s the code that builds my text field: public func makeTextField() -> UITextField { let textField = UITextField() textField.autocorrectionType = .no textField.setContentCompressionResistancePriority(.required, for: .horizontal) textField.setContentCompressionResistancePriority(.required, for: .vertical) if #available(iOS 13.0, *) { textField.smartInsertDeleteType = .no } textField.smartQuotesType = .no textField.smartDashesType = .no textField.autocapitalizationType = .none textField.contentMode = .scaleToFill if let font = attributes[.font] as? UIFont { textField.font = font } if let color = attributes[.foregroundColor] as? UIColor { textField.textColor = color } // Truncate long text at the head let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.lineBreakMode = .byTruncatingHead textField.defaultTextAttributes[.paragraphStyle] = paragraphStyle textField.delegate = self textField.backgroundColor = .clear textField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged) return textField } Entire text is selected when focusing the field if the text is long. What I’ve tried Forcing the caret to the end in textFieldDidBeginEditing: func textFieldDidBeginEditing(_ textField: UITextField) { let end = textField.endOfDocument textField.selectedTextRange = textField.textRange(from: end, to: end) } Doing the same asynchronously (next runloop) to avoid the system overriding selection: func textFieldDidBeginEditing(_ textField: UITextField) { DispatchQueue.main.async { let end = textField.endOfDocument textField.selectedTextRange = textField.textRange(from: end, to: end) } } Despite these, the system still selects all text on focus when the string is long/truncated at the head.
2
0
204
1w
tabViewBottomAccessory in 26.1: View's @State is lost when switching tabs
Any view that is content for the tabViewBottomAccessory API fails to retain its state as of the last couple of 26.1 betas (and RC). The loss of state happens (at least) when the currently selected tab is switched (filed as FB20901325). Here's code to reproduce the issue: struct ContentView: View { @State private var selectedTab = TabSelection.one enum TabSelection: Hashable { case one, two } var body: some View { TabView(selection: $selectedTab) { Tab("One", systemImage: "1.circle", value: .one) { BugExplanationView() } Tab("Two", systemImage: "2.circle", value: .two) { BugExplanationView() } } .tabViewBottomAccessory { AccessoryView() } } } struct AccessoryView: View { @State private var counter = 0 // This guy's state gets lost (as of iOS 26.1) var body: some View { Stepper("Counter: \(counter)", value: $counter) .padding(.horizontal) } } struct BugExplanationView: View { var body: some View { ScrollView { VStack(alignment: .leading, spacing: 16) { Text("(1) Manipulate the counter state") Text("(2) Then switch tabs") Text("BUG: The counter state gets unexpectedly reset!") } .multilineTextAlignment(.leading) } } }
1
2
215
1w
[Want] A View detects one from multiple Gestures.
SwiftUI Gesture cannot detect one of multiple gestures. I made a library for it because one of my apps needs it. library: https://github.com/Saw-000/SwiftUI-DetectGestureUtil I think the function like this library maybe is needed in the core, and can be used with "import SwiftUI", isn't it?
Topic: UI Frameworks SubTopic: SwiftUI
0
0
93
1w
[Want] A View detects one from multiple custom Gestures.
SwiftUI Gesture cannot detect one of multiple gestures. I made a library for it because no default functions for it exists and I need it for my app. https://github.com/Saw-000/SwiftUI-DetectGestureUtil I want to use a function like this library with "import SwiftUI". The function is needed in the core maybe, isn't it?
Topic: UI Frameworks SubTopic: SwiftUI
0
0
96
1w