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

UITableView section flickering with Liquid Glass design
Description of the current implementation: A section, UIView, has been added to UITableView. This section is a UICollectionView that displays an array of images. Each UICollectionViewCell is an image displayed via a UIImageView. Issue: When UITableView is scrolled vertically, the section with the image collection flickers. Attempts made to solve the problem: if #available(iOS 26.0, *) { tableView.bottomEdgeEffect.isHidden = true tableView.topEdgeEffect.isHidden = true tableView.leftEdgeEffect.isHidden = true tableView.rightEdgeEffect.isHidden = true } else { // Fallback on earlier versions } This helped with a similar issue. I tried it on UITableView and UICollectionView, but it didn't work.
1
0
116
4w
Severe Scroll Lag & Header Flickering in Complex SwiftUI Screen with Dynamic Content (GeometryReader + Scroll Direction Detection)
I’m working on a SwiftUI screen where I need to hide a header when the user scrolls down and show it again when the user scrolls up. I’m currently using a ScrollView combined with GeometryReader to detect scroll offset changes and update state variables like isScrolling or isScrollingDown. The issue is that the behavior is inconsistent. When I scroll down, the header hides correctly, but when I scroll back up, the header often doesn’t appear again even though the offset is changing. Sometimes the header comes back with a delay, and other times it never appears at all. Along with this, I’m also seeing noticeable UI lag whenever I try to calculate content height or read multiple geometry values inside the ScrollView. It looks like the frequent state updates inside the scroll offset tracking are causing layout recalculations and frame drops. I’ve tried placing the header in different positions (inside a ZStack aligned to the top, inside the VStack above the ScrollView, and with transitions like .push(from: .top)), but the result is still the same: smooth scrolling breaks, and the header doesn’t reliably animate back when scrolling upward. What I’m looking for is a minimal and efficient approach to detect scroll direction and trigger the header hide/show animation without causing performance issues or recomputing expensive layout values. Any guidance or a simplified pattern that works well for dynamic headers in SwiftUI would be very helpful. if isScrolling { headerStackView() //Includes Navigation Bar .transition( .asymmetric( insertion: .push(from: .top), removal: .push(from: .bottom) ) ) } GeometryReader { outer in let outerHeight = outer.size.height ScrollView(.vertical) { VStack { content() // Heavy view + contains its own ScrollView } .background { GeometryReader { proxy in let contentHeight = proxy.size.height let minY = max( min(0, proxy.frame(in: .named("ScrollView")).minY), outerHeight - contentHeight ) if #available(iOS 17.0, *) { Color.clear .onChange(of: minY) { oldVal, newVal in // Scroll direction detection if (isScrolling && newVal < oldVal) || (!isScrolling && newVal > oldVal) { isScrolling = newVal > oldVal } } } } } } .coordinateSpace(name: "ScrollView") } .padding(.top, 1)
2
0
87
4w
iOS 26.1 adds dark tint under transparent tab bar and ui elements (worked correctly in iOS 26)
After updating from iOS 26 to iOS 26.1, all my transparent system elements (i.e. UITabBar, UIBarButtonItem) started rendering with a dark background tint. In iOS 26 the same configuration looked fully transparent / glassy. The strange part is that the tint only appears in normal UIViewControllers. In UITableViewController the tab bar still looks correct and transparent, even on iOS 26.1. I am using the same appearance code as before: func setupTabBarAppearance() { guard let tabBar = tabBarController?.tabBar else { return } if #available(iOS 26.0, *) { let appearance = UITabBarAppearance() appearance.configureWithTransparentBackground() appearance.backgroundColor = .clear appearance.backgroundEffect = nil appearance.shadowColor = .clear tabBar.standardAppearance = appearance tabBar.scrollEdgeAppearance = appearance tabBar.isTranslucent = true tabBar.backgroundColor = .clear tabBar.barTintColor = .clear } else { tabBar.isTranslucent = true tabBar.backgroundImage = UIImage() tabBar.shadowImage = UIImage() tabBar.backgroundColor = .clear } } I tried removing backgroundEffect, forcing .clear colors, using configureWithDefaultBackground, changing edgesForExtendedLayout, extendedLayoutIncludesOpaqueBars, etc. I noticed that if I change Liquid Glass in iOS 26 settings from Clear to Tinted, then I get a black tint everywhere and the interface becomes consistent, but not the way I want. Nothing removes the new dark tint in iOS 26.1. Is this an intentional change in iOS 26.1, a bug, or is there a new way to make the tab bar fully transparent again?
1
0
100
4w
how to navigate programmatically without navigation link?
Hello. I'm making an app with several different views. I'm trying to switch views using a button but I can't seem to figure out how. I know Navigation Links work, but my case doesn't work. The reasons for this are because I need to run other code when they click the button and I don't want them to be able to navigate back (to CustomizationView/CreateAccountView). I know that you can hide the back button but my problem with that is the fact that i will be navigating to a view (MainView) that will also have navigation buttons in it, so if i'm thinking correctly, the button will be hidden but when they press the next navigationlink (in MainView) it will show again and then they can go back (to CustomizationView/CreateAccountView). i don't want them to go back because they will be navigating from a login/account view that wont be needed anymore. I'm currently using .fullScreenCover() and it works fine except for performance (I'm assuming). here's the code: import SwiftUI struct CustomizationView: View { @State private var showMain = false var body: some View { Button("Done") { // some more code here showMain = true } .fullScreenCover(isPresented: $showMain) { MainView() } } } here's a visual for the navigation if you're confused
2
0
107
4w
Recommended Way to Implement Digital Crown Zoom + Drag for Images on watchOS
I’m trying to implement smooth zoom and drag interactions for an image on watchOS—similar to the Photos app. DTS recommended using digitalCrownRotation + scaleEffect in SwiftUI, and ChatGPT also suggests a similar approach. However, the experience still isn’t as smooth or polished as the Photos app. Before I commit fully to this direction, I want to confirm: 1. Is SwiftUI with digitalCrownRotation, scaleEffect, and DragGesture the officially recommended approach for zoom + pan on watchOS? 2. Is there any public API that provides built-in Photos-style behavior, or is a custom SwiftUI implementation expected? 3. Are there best-practice patterns for smooth scaling, maintaining image bounds, and constrained panning? Thanks for any guidance
Topic: UI Frameworks SubTopic: SwiftUI
1
0
89
4w
UIInputView is not deallocated from memory
When a subclass of UIInputView is created programmatically, a memory leak occurs. This issue can be easily reproduced even with a very simple sample project, so I’m submitting this report along with a minimal reproducible example. When a custom view subclassing UIInputView is instantiated in code, _InputViewContent retains the custom view, and the custom view also holds a reference back to _InputViewContent, creating a strong reference cycle that prevents deallocation. The issue consistently occurs and has been confirmed on Xcode 16.4, 26.0, and 26.1. As a workaround, initializing the view via Storyboard allows it to be properly deallocated from memory. (Please refer to the CustomInputView in the attached sample code.) import UIKit final class LeakInputView: UIInputView { deinit { print("LeakInputView deinit") // not called } } final class CustomInputView: UIInputView { required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } override init(frame: CGRect, inputViewStyle: UIInputView.Style) { super.init(frame: frame, inputViewStyle: inputViewStyle) } deinit { print("CustomInputView deinit") // called } } extension CustomInputView { static func loadFromNib() -> CustomInputView { let nib = UINib(nibName: "CustomInputView", bundle: nil) guard let view = nib.instantiate(withOwner: nil, options: nil).first as? CustomInputView else { fatalError("Failed to load CustomInputView from nib.") } return view } } final class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .red LeakInputView() LeakInputView() LeakInputView() CustomInputView.loadFromNib() CustomInputView.loadFromNib() CustomInputView.loadFromNib() DispatchQueue.main.async { print("Next runloop tick") } } }
Topic: UI Frameworks SubTopic: UIKit
1
0
120
4w
32 byte NSNumber memory leak - how to fix?
I use the following bit of code to snapshot a View as a UIImage, but it's causing a memory leak: extension View { @ViewBuilder func snapshot(trigger: Bool, onComplete: @escaping (UIImage) -> ()) -> some View { self.modifier(SnapshotModifier(trigger: trigger, onComplete: onComplete)) } } fileprivate struct SnapshotModifier: ViewModifier { var trigger: Bool var onComplete: (UIImage) -> () @State private var view: UIView = .init(frame: .zero) func body(content: Content) -> some View { content .background(ViewExtractor(view: view)) .compositingGroup() .onChange(of: trigger) { generateSnapshot() } } private func generateSnapshot() { if let superView = view.superview?.superview { let render = UIGraphicsImageRenderer(size: superView.bounds.size) let image = render.image { _ in superView.drawHierarchy(in: superView.bounds, afterScreenUpdates: true) } onComplete(image) } } } fileprivate struct ViewExtractor: UIViewRepresentable { var view: UIView func makeUIView(context: Context) -> UIView { view.backgroundColor = .clear return view } func updateUIView(_ uiView: UIView, context: Context) { // No process } } Taking the snapshot is triggered like this: struct ContentView: View { @State private var triggerSnapshot: Bool = false var body: some View { Button("Press to snapshot") { triggerSnapshot = true } TheViewIWantToSnapshot() .snapshot(trigger: triggerSnapshot) { image in // Save the image; you don't have to do anything here to get the leak. } } } I'm not the best at Instruments, and this is what the Leaks template produces. There are no method names, just memory addresses: Is this leak in an internal iOS library, is there something wrong with Instruments, or am I missing something obvious in my code? Thanks.
Topic: UI Frameworks SubTopic: UIKit Tags:
3
0
109
Nov ’25
Tip always displayed with TipKit
Why a TipKit configured with a weekly frequency, on the following example, when the app is launched on the View1, the tip is displayed. I thought that going to View2 and come back to View1 should not redisplayed the tip (at least until one week). What do I miss? import SwiftUI import TipKit struct FavoriteLandmarkTip: Tip { var title: Text { Text("Save as a Favorite") } var message: Text? { Text("Your favorite landmarks always appear at the top of the list.") } var image: Image? { Image(systemName: "star") } } @main struct LandmarkTips: App { var body: some Scene { WindowGroup { TabView { View1() .tabItem { Label("View1", systemImage: "house") } View2() .tabItem { Label("View2", systemImage: "house") } } .task { do { // uncomment to reset all tips status // try? Tips.resetDatastore() try Tips.configure([ .displayFrequency(.weekly), .datastoreLocation(.applicationDefault) ]) } catch { print("Error initializing TipKit \(error.localizedDescription)") } } } } } struct View1: View { let favoriteLandmarkTip = FavoriteLandmarkTip() var body: some View { VStack { TipView(favoriteLandmarkTip, arrowEdge: .bottom) Image(systemName: "star") } } } struct View2: View { var body: some View { Text("View2") } }
1
0
40
Nov ’25
Layout issues occur when the Picker style is segmented on macOS.
When I run the following code and change "Is On", I get a problem with the layout of the Picker. There is no problem when using Text(), but when using only Image, it works fine on iOS but there is a problem on macOS. Tested on macOS 26.1, Xcode 26.1. import SwiftUI struct ContentView: View { @State var model = Model() var body: some View { Form { Picker("Category", selection: $model.category) { ForEach(Category.allCases) { item in Image(systemName: item.icon) .tag(item) } } .pickerStyle(.segmented) Toggle("Is On", isOn: $model.isOn) } .formStyle(.grouped) } } struct Model { var category: Category = .a var isOn: Bool = false } enum Category: Int, Identifiable, CaseIterable { case a, b, c var id: Int { rawValue } var icon: String { switch self { case .a: return "a.circle.fill" case .b: return "b.circle.fill" case .c: return "c.circle.fill" } } var name: String { switch self { case .a: return "a" case .b: return "b" case .c: return "c" } } } code-block
1
0
38
Nov ’25
Folder icon change in FileProvider mount in Finder
We are creating a Replicated FileProvider based application, where we need to change folder icons for root level folders. I tried below two approaches. This using NSFileProviderDecorations + Custom UTType, this changed the UI as shown: This using Custom UTType, this had no UI change: How can we change the default folder icon, to our custom icon?
3
0
207
Nov ’25
SwiftUI .toolbar(placement: .keyboard) item not exposed to accessibility on iOS 26.1 (affects VoiceOver + XCUITest)
Description On iOS 26.1, a ToolbarItem placed in .keyboard is no longer exposed to the accessibility hierarchy. As a result: VoiceOver cannot focus or activate the toolbar button XCUITest cannot discover the element, making the UI impossible to test TextEditor() .toolbar { ToolbarItem(placement: .keyboard) { Button("Done") { /* action */ } } } This worked correctly on previous iOS versions. The button appears visually but is missing from both VoiceOver navigation and XCUI accessibility queries. Steps to Reproduce Create a new SwiftUI project. Use a simple text field with a keyboard toolbar button. Run on an iOS 26.1 device or simulator. Focus the text field to show the keyboard. Turn on VoiceOver and attempt to navigate to the toolbar button. Run an XCUITest attempting to locate the button
1
0
77
Nov ’25
screenshot issue
I know iPhone Cannot prohibit screenshots, but I have seen someone else's solution, which is to capture a white page instead of the current design page when taking screenshots. I want to use swift implement iPhone The photo generated when taking a screenshot is a white screen, and I don't want my page to be seen by others
Topic: UI Frameworks SubTopic: General
2
0
97
Nov ’25
How Do Commercial Apps Extract Screen Time Data on iOS?
Looking at Brainrot's UI, they display both "Screen Time: 6h 31m" and a calculated "Health: 91/100" score with a "Tap to Fix" button. This suggests manual sync or a workaround. Specific Questions: Can DeviceActivityReport extensions communicate data back to the main app? (CloudKit, Notifications, Shared files?) Can extensions write to UserDefaults on physical devices? Do commercial apps rely on manual user sync? Is there an alternative API I'm overlooking? Do threshold-based approximations work reliably for daily tracking? I can extract exact minutes in the extension but can't export them to the main app due to sandbox restrictions. Either a technical solution or confirmation that manual sync is the industry standard would help greatly.
1
0
57
Nov ’25
TabView + NavigationStacks broken on iOS 26.1
Broken TabView + NavigationStacks functionality on iOS 26.1. Even the most basic navigation made impossible. Example: TabView { Tab(...) { NavigationStack(path: $homePath) { HomeView() .navigationDestination { ... } } } Tab(...) { NavigationStack(path: $settingsPath) { SettingsView() .navigationDestination { ... } } } } Anything passed to settingsPath is just ignored and would never appear onscreen. (26.0 and prior versions work as expected.) Are there any workarounds?
1
1
105
Nov ’25
MainMenu issue if I start a new Xcode Objective-C Cocoa Mac Storyboard/XIB application.
I'm reading a bit outdated book about Cocoa/Objective-C applications development and I'm trying to code some examples. And so I ended up with an almost empty NSDocument-based app with runtime errors like that: Internal inconsistency in menus - menu <NSMenu: 0xbc726d040> Title: Window Supermenu: 0xbc726d080 (Main Menu), autoenable: YES Previous menu: 0x0 (None) Next menu: 0x0 (None) Items: ( "<NSMenuItem: 0xbc6fcd9a0 Minimize, ke='Command-M'>", "<NSMenuItem: 0xbc6fcda40 Zoom, ke mask=''>", "<NSMenuItem: 0xbc6fcdae0, separator, ke mask=''>", "<NSMenuItem: 0xbc6fcd900 Bring All to Front, ke mask=''>" ) believes it has <NSMenu: 0xbc726d080> Title: Main Menu Supermenu: 0x0 (None), autoenable: YES Previous menu: 0x0 (None) Next menu: 0x0 (None) Items: ( ) as a supermenu, but the supermenu does not seem to have any item with that submenu It looks like as if the menu tries to include itself as a submenu. Am I right? I have no ideas what led to this. If I'm not mistaken this has started since macOS Tahoe. The code that is not a boilerplate one I have: // Document.m #import "Document.h" @implementation Document @synthesize text; - (NSString *)windowNibName { return @"SampleDocument"; } - (void)windowControllerDidLoadNib:(NSWindowController *)aController { [super windowControllerDidLoadNib:aController]; if (self.text == nil) { self.text = @""; } self.textField.stringValue = self.text; } - (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError { self.text = self.textField.stringValue; return [self.text dataUsingEncoding:NSUTF8StringEncoding]; } - (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError { if ([data length] > 0) { NSString * string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; self.text = string; } else { self.text = @""; } return YES; } + (BOOL)autosavesInPlace { return YES; } @end There are two xib's: MainMenu.xib and Document.xib but I won't include them here. Please advise how to fix this menu issue.
1
0
146
Nov ’25
Request Review alert is unresponsive in iOS 26.1
Try this simple code: import SwiftUI import StoreKit struct ReviewView: View { @Environment(\.requestReview) var requestReview var body: some View { Button("Leave a review") { requestReview() } } } When the Review Alert shows, the "Not Now" button is disabled for some reason!? It was always tappable in all iOS versions that I remember. And there is no way to opt out, unless the user taps on the stars first. Is it a bug or a feature? Thanks for looking into it!
4
1
758
Nov ’25
NavigationStack Back Button obscured in MacOS
A MacOS SwiftUI app using WindowGroup with a NavigationStack results in having the navigation title overlay the back button. Note that this does not occur if a tabbed interface is used. The work around is simply to hide the navigation bar back button and add a tool bar item that is custom back button. I found a fix on this forum, and it was similar to: #if os(macOS) .navigationBarBackButtonHidden(true) .toolbar { ToolbarItem(placement: .navigation) { Button(action: { dismiss() }) { Label("Back", systemImage: "arrow.left.circle") } } } #endif modifying the NavigationLink targets and where the dismiss() function was provided by: @Environment(\.dismiss) private var dismiss Is there any means to sign up for a notification to inform me that this bug has been fixed?
Topic: UI Frameworks SubTopic: SwiftUI
2
0
133
Nov ’25
PKPaymentButtonType.plain renders blank on iOS 26.1 when built with Xcode 26 (snapshot returns transparent image)
Hello Apple Team, I’ve encountered a regression in iOS 26.1 when building my app with Xcode 26 (iOS 26 SDK). The issue affects PKPaymentButtonType.plain, which now renders as fully invisible and produces transparent snapshots, even though the same code worked correctly in previous Xcode/iOS versions. This has a real-world impact because many apps generate static images from PKPaymentButton for payment selection UIs using UIGraphicsImageRenderer, layer.render(in:), or custom snapshot utilities. When using PKPaymentButton(paymentButtonType: .plain, paymentButtonStyle: .black) on iOS 26.1, when built with Xcode 26, the button: Appears blank / invisible Cannot be snapshotted Produces a fully transparent UIImage, even though the CGImage object exists Behaves differently than older SDKs (Xcode 16.x / iOS < 26.1 This regression only appears when compiling with the new SDK. Other button types work fine. Expected Behavior .plain button should render glyphs as documented snapshot generated via UIGraphicsImageRenderer or drawHierarchy(in:) should produce a visible image Behavior should be consistent with older SDKs unless explicitly deprecated in release notes Expected Behavior .plain button should render glyphs as documented Snapshot generated via UIGraphicsImageRenderer or drawHierarchy(in:) should produce a visible image Behavior should be consistent with older SDKs unless explicitly deprecated in release notes Actual Behavior .plain button renders no glyph at all Snapshot image is fully transparent (alpha = 0), even though size and CGImage metadata are correct Only happens when built with Xcode 26 SDK Same build from Xcode 16.x does not reproduce the issue Steps to Reproduce Create a minimal sample project in Xcode 26 Add the following code: let button = PKPaymentButton(paymentButtonType: .plain, paymentButtonStyle: .black) button.frame = CGRect(x: 0, y: 0, width: 180, height: 48) let renderer = UIGraphicsImageRenderer(size: button.bounds.size) let image = renderer.image { _ in button.drawHierarchy(in: button.bounds, afterScreenUpdates: true) } print(image) Run on iOS 26.1 device or simulator Observe that: The button appears visually empty The generated image is fully transparent Environment Xcode: 26.x (iOS 26 SDK) iOS: 26.1 (iPhone 15 Pro tested) Device: Real device Framework: UIKit + PassKit Button type: .plain ONLY Other types: .pay/.buy/.checkout = OK
2
1
154
Nov ’25