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

Creating NSStatusBar.system.statusItem generates console warning
Putting: let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) at the top of AppDelegate.swift and no other code at all generates the warning below in the console when the app runs. Looks benign but it sure would be great to not have that happen. Anyone figure out how to stop this other than muting the warning? I tried all kinds of exotic deferring but that just makes the code brittle and unreadable. Here's the warning: It's not legal to call -layoutSubtreeIfNeeded on a view which is already being laid out. If you are implementing the view's -layout method, you can call -[super layout] instead. Break on void _NSDetectedLayoutRecursion(void) to debug. This will be logged only once. This may break in the future. Xcode 26.5, 26.4 - macOS 26.5.1
Topic: UI Frameworks SubTopic: AppKit
2
0
219
Jun ’26
How to animate NSSegmentedControl on macOS 26?
I noticed that in Xcode 27 Beta 1 on macOS 27 Beta 1, changing the selection of the segmented control used to switch between the Sidebar and Inspector tabs is animated. However, the standard segmented controls used by NSTabView/NSTabViewController, as well as a regular NSSegmentedControl, do not appear to have any such animation on macOS 27. I also tried using the animator proxy: segmentedControl.animator().selectedSegment = index but this did not change the behavior. How can I implement the same kind of segmented control selection animation that Xcode uses? Is there a public API for this, or is it achieved through a different mechanism?
Topic: UI Frameworks SubTopic: AppKit
1
0
218
Jun ’26
Back gesture not disabled with navigationBarBackButtonHidden(true) when using .zoom transition
[Submitted as FB22226720] For a NavigationStack destination, applying .navigationBarBackButtonHidden(true) hides the back button and also disables the interactive left-edge back gesture when using the standard push navigation transition. However, when the destination uses .navigationTransition(.zoom), the back button is hidden but the left-edge back gesture is still available—it can still be dismissed even though back is intentionally suppressed. This creates inconsistent behavior between navigation transition styles. navigationBarBackButtonHidden(_:) works with a standard push transition, but not with .navigationTransition(.zoom). In the code below, .interactiveDismissDisabled(true) is also applied as another attempt to suppress the back-swipe gesture, but it has no effect. As a result, there’s currently no clean way to prevent back navigation when using the zoom transition. REPRO STEPS Create an iOS project then replace ContentView with code below, build and run. Leave nav type set to List Push. Open an item. Verify there is no back button, then try the left-edge back gesture. Return to the root view. Change nav type to Grid Zoom. Open an item. Verify there is no back button, then try the left-edge back gesture. ACTUAL In List Push mode, the left-edge back gesture is prevented. In Grid Zoom mode, the back button is hidden, but the left-edge back gesture still works and returns to the previous view. EXPECTED Behavior should be consistent across navigation transition styles. If this configuration is meant to suppress interactive backward navigation for a destination, it should also suppress the left-edge back gesture when using .navigationTransition(.zoom). SCREEN RECORDING SAMPLE CODE struct ContentView: View { private enum NavigationMode: String, CaseIterable { case listPush = "List Push" case gridZoom = "Grid Zoom" } @Namespace private var namespace @State private var navigationMode: NavigationMode = .listPush private let colors: [Color] = [.red, .blue] var body: some View { NavigationStack { VStack(spacing: 16) { Picker("Navigation Type", selection: $navigationMode) { ForEach(NavigationMode.allCases, id: \.self) { mode in Text(mode.rawValue).tag(mode) } } .pickerStyle(.segmented) if navigationMode == .gridZoom { HStack { ForEach(colors.indices, id: \.self) { index in NavigationLink(value: index) { VStack { RoundedRectangle(cornerRadius: 14) .fill(colors[index]) .frame(height: 120) Text("Grid Item \(index + 1)") .font(.subheadline.weight(.medium)) } .padding(12) .frame(maxWidth: .infinity) .background(.quaternary.opacity(0.25), in: RoundedRectangle(cornerRadius: 16)) .matchedTransitionSource(id: index, in: namespace) } .buttonStyle(.plain) } } } else { ForEach(colors.indices, id: \.self) { index in NavigationLink(value: index) { HStack { Circle() .fill(colors[index]) .frame(width: 24, height: 24) Text("List Item \(index + 1)") Spacer() Image(systemName: "chevron.right") .foregroundStyle(.secondary) } .padding() .background(.quaternary.opacity(0.25), in: RoundedRectangle(cornerRadius: 12)) } .buttonStyle(.plain) } } Spacer() } .padding(20) .navigationTitle("Prevent Back Swipe") .navigationSubtitle("Compare Grid Zoom vs List Push") .navigationDestination(for: Int.self) { index in if navigationMode == .gridZoom { DetailView(color: colors[index]) .navigationTransition(.zoom(sourceID: index, in: namespace)) } else { DetailView(color: colors[index]) } } } } } private struct DetailView: View { @Environment(\.dismiss) private var dismiss let color: Color var body: some View { ZStack { color.ignoresSafeArea() Text("Try left-edge swipe back") .font(.title.bold()) .multilineTextAlignment(.center) .padding(.horizontal, 24) } .navigationBarBackButtonHidden(true) .interactiveDismissDisabled(true) .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Close", action: dismiss.callAsFunction) } } } }
3
0
837
Jun ’26
TextKit 2 + SwiftUI (NSViewRepresentable): NSTextLayoutManager rendering attributes don’t reliably draw/update
I’m embedding an NSTextView (TextKit 2) inside a SwiftUI app using NSViewRepresentable. I’m trying to highlight dynamic subranges (changing as the user types) by providing per-range rendering attributes via NSTextLayoutManager’s rendering-attributes mechanism. The issue: the highlight is unreliable. Often, the highlight doesn’t appear at all even though the delegate/data source is returning attributes for the expected range. Sometimes it appears once, but then it stops updating even when the underlying “highlight range” changes. This feels related to SwiftUI - AppKit layout issue when using NSViewRepresentable (as said in https://developer.apple.com/documentation/swiftui/nsviewrepresentable). What I’ve tried Updating the state that drives the highlight range and invalidating layout fragments / asking for relayout Ensuring all updates happen on the main thread. Calling setNeedsDisplay(_:) on the NSViewRepresentable’s underlying view. Toggling the SwiftUI view identity (e.g. .id(...)) to force reconstruction (works, but too expensive / loses state). Question In a SwiftUI + NSViewRepresentable setup with TextKit 2, what is the correct way to make NSTextLayoutManager re-query and redraw rendering attributes when my highlight ranges change? Is there a recommended invalidation call for TextKit 2 to trigger re-rendering of rendering attributes? Or is this a known limitation when hosting NSTextView inside SwiftUI, where rendering attributes aren’t reliably invalidated? If this approach is fragile, is there a better pattern for dynamic highlights that avoids mutating the attributed string (to prevent layout/scroll jitter)?
4
0
539
Jun ’26
UITextView for displaying long text?
My app displays vertically scrollable text to the user which could be as short as a single screen or as long as a book chapter: imagine something like an e-book reader which uses scrolling rather than page-turning. A long time ago when development first started, I tried using UITextView, but the size of text that could be handled was quite limited (a figure of 32767 points seems to stick in the memory). Accordingly I came up with a custom solution in which a UIScrollView handled scrolling gestures and a custom UIView rendered just the part of the text that was visible at that time. That works, but it becomes cumbersome to add support for features such as selection handles and loupes. 18 years later, is there a more smoothly integrated way of displaying long scrollable text?
Topic: UI Frameworks SubTopic: UIKit
2
0
210
Jun ’26
Debugging multi-window AppKit apps: Identifying the window associated with a breakpoint
When working on a multi-window AppKit app, how do you identify which window instance is associated with the current breakpoint? The same question applies when using LLDB. If execution stops inside an object that can exist in more than one window, such as a shared NSViewController subclass, how do you know which window’s object you are currently inspecting? Does Xcode provide a mechanism for showing the NSWindow associated with the current view, view controller or responder while debugging? My current approach is to print object identities and compare them manually. For example, if several identical windows are open, I might print the current object and its window: print(self, #function) Then I interact with one window, make a note of the printed memory addresses in the console, switch to another window and compare the output. This works, but it feels manual. I am not dealing with different window subclasses. The windows may be instances of the same class and may contain instances of the same view controller classes. I simply want an easier way to distinguish which window instance I am debugging. Is there a recommended Xcode, LLDB or AppKit workflow for this?
1
0
338
Jun ’26
Hide standard window buttons
How do I permanently hide the standard window buttons(Buttons on top left; close, minimize and zoom) In my app, I hide the standard buttons and put my own custom buttons. Some users have reported that the standard buttons appear again making the app look buggy and confuses the users At present I use following code to remove the buttons standardWindowButton(.closeButton)?.removeFromSuperview() standardWindowButton(.miniaturizeButton)?.removeFromSuperview() standardWindowButton(.zoomButton)?.removeFromSuperview() } I have to call this code from multiple places like on window initialization, when appearance changes and when the window size changes. I tried creating window without the titled stylemask, but it has other down sides like the standard window decoration is entirely skipped by the system. The resizing also is unpredictable. My question is, what is the right way to remove/hide the standard window buttons?
Topic: UI Frameworks SubTopic: AppKit
1
0
238
Jun ’26
Handling View Creation for Heterogeneous Data
In my project (an Package), I have created an Manager (can be classified as an ViewModel) that will handle state updates throughout the Package Component view: Note: The code is simplified for better understanding and to focus on principles behind things I did. The manager does complex things during state updates. public class ComponentManager: ObservedObject { @Published var rows: [any RowProtocol] = [] func updateState(_ newState: any RowProtocolData, id: String) { guard let index = rows.firstIndex(where: { $0.id == id }) else { return } rows[index].updateState(newState) } func getState(id: String) -> any RowProtocolData? { guard let index = rows.firstIndex(where: { $0.id == id }) else { return nil } return rows[index].state } } The RowProtocol is defined as follows: public protocol RowStateProtocol {} public protocol RowProtocol: Identifiable { associatedtype State: RowStateProtocol associatedtype RowView: View var id: String { get } var state: State { get } func updateState(_ newState: State) @MainActor @ViewBuilder func renderRow() -> RowView } extension RowProtocol { func updateState(_ newState: any RowProtocolData) { guard let newState = newState as? State else { return } self.updateState(newState) } } Then in Component View, I need to render the rows based on the underlying type of the row, this where the renderRow() comes in: struct ComponentView: View { @ObservedObject var manager: ComponentManager var body: some View { List { ForEach(manager.rows, id: \.id) { row in HStack { // This HStack prevent List from initing all rows due to AnyView. AnyView(row.renderRow()) } } } } } The row views will be accepting binding to the state of the row and update their state, let says we have a TextRow and a ToggleRow: struct TextRow: RowProtocol { var id: String var state: TextRowState func updateState(_ newState: TextRowState) { self.state = newState } } struct ToggleRow: RowProtocol { var id: String var state: ToggleRowState func updateState(_ newState: ToggleRowState) { self.state = newState } } In this, offcourse we cannot create an binding directly to the state of the row, since the state are through the manager and the row data won't have access to the manager. So I created an property wrapped that use the closures passed by the manager into environment to create the binding and an view that will give the binding to the content view: extenstion EnvironmentValues { @Entry internal var getState: (String) -> any RowStateProtocol? @Entry internal var updateState: (any RowStateProtocol, String) -> Void } @propertyWrapper struct RowStateBinding<State: RowStateProtocol & Equatable>: DynamicProperty { @Environment(\.getState) private var getState @Environment(\.updateState) private var updateState private let id: String init(id: String) { self.id = id } var wrappedValue: State { get { getState(id) as! State } nonmutating set { if wrappedValue != newValue { // only update for an new change, since set can be triggered for any number of reasons. updateState(newValue, id) } } } var projectedValue: Binding<State> { Binding( get: { self.wrappedValue }, set: { newValue in self.wrappedValue = newValue } ) } } struct RowStateBindingView<Content: View, State: RowStateProtocol & Equatable>: View { @RowStateBinding<State> private var state: State private let content: (Binding<State>) -> Content init(id: String, @ViewBuilder content: @escaping (Binding<State>) -> Content) { self._state = RowStateBinding(id: id) self.content = content } var body: some View { content($state) } } and in the renderRows: struct TextRowView: View { @Binding var text: TextRowState var body: some View { TextField("Enter text", text: $text.text) } } extension TextRow { func renderRow() -> some View { RowStateBindingView(id: id) { state in TextField("Enter text", text: state.text) } } } struct ToggleRowView: View { @Binding var state: ToggleRowState var body: some View { Toggle("Toggle", isOn: $state.isOn) } } extension ToggleRow { func renderRow() -> some View { RowStateBindingView(id: id) { state in Toggle("Toggle", isOn: state.isOn) } } } This way, I can adopt any view as an row view and most importantly, the view can be completely independent of the manager and used as an standalone view. Also clients of the library can create their own custom rows by just conforming to the RowProtocol and creating the view for it, without worrying about how the state management works. The manager will handle all the state updates. I prefer using stucts over classes for rows and states, since its easier to manage state updates. What do you think about this approach? Do you see any potential issues with this? Is there a better way to achieve this?
0
0
102
Jun ’26
Crash occured in UIDatePicker Calendar type
I am encountering a consistent, reproducible crash in our app when presenting a UIDatePicker configured with the calendar style. The crash triggers every single time the picker is invoked and points directly to the modern date picker's internal UICollectionView. The Exception: *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UICollectionView internal inconsistency: attempted to set layout with the collection view requiring a reload' let datePicker = UIDatePicker() datePicker.datePickerMode = .date datePicker.preferredDatePickerStyle = .compact This crash is occuring in inline style too when I try to open the calendar. I tried this in other apps. It works fine. I didn't override any collectionView layouts
1
0
130
Jun ’26
Summary of iOS/iPadOS 26 UIKit bugs related to UISearchController & UISearchBar using scope buttons
All of these issues appear when the search controller is set on the view controller's navigationItem and the search controller's searchBar has its scopeButtonTitles set. So far the following issues are affecting my app on iOS/iPadOS 26 as of beta 7: When the scopeBarActivation of UISearchController is set to .onSearchActivation, the preferredSearchBarPlacement of the navigationItem is set to .integratedButton, and the searchBarPlacementAllowsToolbarIntegration is set to false (forcing the search icon to appear in the nav bar), on both iPhones and iPads, the scope buttons never appear. They don't appear when the search is activated. They don't appear when any text is entered into the search bar. FB19771313 I attempted to work around that issue by setting the scopeBarActivation to .manual. I then show the scope bar in the didPresentSearchController delegate method and hide the scope bar in the willDismissSearchController. On an iPhone this works though the display is a bit clunky. On an iPad, the scope bar does appear via the code in didPresentSearchController, but when any scope bar button is tapped, the search controller is dismissed. This happens when the app is horizontally regular. When the app on the iPad is horizontally compact, the buttons work but the search bar's text is not correctly aligned within the search bar. Quite the mess really. I still need to post a bug report for this issue. But if issue 1 above is fixed then I don't need this workaround. When the scopeBarActivation of UISearchController is set to .onSearchActivation, the preferredSearchBarPlacement of the navigationItem is set to .stacked, and the hidesSearchBarWhenScrolling property of the navigationItem is set to false (always show the search bar), and this is all used in a UITableViewController, then upon initial display of the view controller on an iPhone or iPad, you are unable to tap on the first row of the table view except on the very bottom of the row. The currently hidden scope bar is stealing the touches. If you activate and then cancel the search (making the scope bar appear and then disappear) then you are able to tap on the first row as expected. The initially hidden scope bar also bleeds through the first row of the table. It's faint but you can tell it's not quite right. Again, this is resolved by activating and then canceling the search once. FB17888632 When the scopeBarActivation of UISearchController is set to .onSearchActivation, the preferredSearchBarPlacement of the navigationItem is set to integrated or .integratedButton, and the toolbar is shown, then on iPhones (where the search bar/icon appears in the toolbar) the scope buttons appear (at the top of the screen) the first time the search is activated. But if you cancel the search and then activate it again, the search bar never appears a second (or later) time. On an iPad the search bar/icon appears in the nav bar and you end up with the same issue as #1 above. FB17890125 Issues 3 and 4 were reported against beta 1 and still haven't been fixed. But if issue 1 is resolved on iPhone, iPad, and Mac (via Mac Catalyst), then I personally won't be affected by issues 2, 3, or 4 any more (but of course all 4 issues need to be fixed). And by resolved, I mean that the scope bar appears and disappears when it is supposed to each and every time the search is activated and cancelled (not just the first time). The scope bar doesn't interfere with touch events upon initial display of the view controller. And there are no visual glitches no matter what the horizontal size class is on an iPad. I really hope the UIKit team can get these resolved before iOS/iPadOS 26 GM.
11
6
1.9k
Jun ’26
UIView wrapper around a View
I couldn't decide whether to post this question here or in SwiftUI Q&A as there's a lot of overlaps. We're trying to create something similar to UIViewRepresentable for UIKit. This might not work for complicated cases where the View has many pieces but as long as it works for simple cases, we're happy. The only problem right now is figuring out the correct height. Currently, the height anchor is assigned to CGFloat.greatestFiniteMagnitude, which works but when inspecting the layout in View Hierarchy, it appears the wrapped view is getting stretched all the way down. Also, sometimes View Hierarchy isn't able to draw the wrapped View and I'm unsure if it's a problem of View Hierarchy or our implementation. final public class SwiftUIConfigurationContainerView<T: View>: UIView { private var contentView: UIView? public override var intrinsicContentSize: CGSize { contentView?.intrinsicContentSize ?? super.intrinsicContentSize } private var preferredContentSize: CGSize? public init(@ViewBuilder _ content: @escaping () -> T) { super.init(frame: .zero) setUpContentView(content) } @available(*, unavailable) required init?(coder: NSCoder) { return nil } private func setUpContentView(_ content: @escaping () -> T) { let contentView = UIHostingConfiguration { [weak self] in VStack(spacing: .zero) { content() .onGeometryChange(for: CGSize.self, of: \.size) { size in self?.preferredContentSize = size self?.invalidateIntrinsicContentSize() } .frame(maxWidth: .infinity, alignment: .center) Spacer(minLength: .zero) } } .minSize(width: .zero, height: .zero) .margins(.all, .zero) .makeContentView() self.contentView = contentView addSubview(contentView) contentView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ contentView.leadingAnchor.constraint(equalTo: leadingAnchor), contentView.trailingAnchor.constraint(equalTo: trailingAnchor), contentView.topAnchor.constraint(equalTo: topAnchor), contentView.heightAnchor.constraint(equalToConstant: CGFloat.greatestFiniteMagnitude), ]) } }
0
0
247
Jun ’26
How to detect backspace in SwiftUI TextField without falling back to UIViewRepresentable?
I'm building a multi-box PIN/OTP input in SwiftUI. In UIKit, I used UITextFieldDelegate to detect backspace presses on an empty field to move focus backward. SwiftUI’s .onChange(of: text) only triggers when text is actually deleted, completely missing backspaces on an already empty field. Is there a pure SwiftUI way to handle this now, or are we still forced to wrap UITextField via UIViewRepresentable?
1
0
129
Jun ’26
Source view disappearing when interrupting a zoom navigation transition
When I use the .zoom transition in a navigation stack, I get a glitch when interrupting the animation by swiping back before it completes. When doing this, the source view disappears. I can still tap it to trigger the navigation again, but its not visible on screen. This seems to be a regression in iOS 26, as it works as expected when testing on iOS 18. Has someone else seen this issue and found a workaround? Is it possible to disable interrupting the transition? Filed a feedback on the issue FB19601591 Screen recording: https://share.icloud.com/photos/04cio3fEcbR6u64PAgxuS2CLQ Example code @State var showDetail = false @Namespace var namespace var body: some View { NavigationStack { ScrollView { showDetailButton } .navigationTitle("Title") .navigationBarTitleDisplayMode(.inline) .navigationDestination(isPresented: $showDetail) { Text("Detail") .navigationTransition(.zoom(sourceID: "zoom", in: namespace)) } } } var showDetailButton: some View { Button { showDetail = true } label: { Text("Show detail") .padding() .background(.green) .matchedTransitionSource(id: "zoom", in: namespace) } } }
Topic: UI Frameworks SubTopic: SwiftUI
20
25
2.5k
Jun ’26
Programatic scroll edge effect for NSScrollView
Just like NSScrollView lets us programmatically set the contentInset in parallel to automaticallyAdjustsContentInsets, I think there should be similar functionality for blurring effect caused by scroll edge effect. I should be able programmatically set it. If the user is manually setting the contentInset then they can simply set a boolean, which when enabled will show edge effect when the scroll document goes outside the area of inset. Eg: scrollView.contentInsets = NSEdgeInsets(top: 100, left: 0, bottom: 0, right: 0) For contentInset like above set by user, they could set edge effect in two ways Automatically: scrollView.enableEdgeEffectOutsideInsets = true // This will apply edge effect based on frame size of contentInsets Programmatically: scrollView.edgeInsetEffectFrame = NSRect...
Topic: UI Frameworks SubTopic: AppKit
5
1
354
Jun ’26
Is there a better way to hide a view in a custom Layout other than placing it off-screen?
I have a custom Layout that places a number of labels for a cell footer in a certain way based on the available width that needs to conditionally hide those views that do not entirely fit anymore (based on some priorities I specify). Currently I simply move the subviews that do not fit anymore off-screen and use clipping to hide them outside the layout, as I did not find an "official" way to hide / exclude a subview from a Layout. Does anyone know a better / nicer way to do this in SwiftUI?
Topic: UI Frameworks SubTopic: SwiftUI
0
0
60
Jun ’26
AsyncRenderer stack limit
We've been getting stack overflows in code we don't control, in the background AsyncRenderer thread in a chain of calls to updateInheritedViewAsync. But the stack is less than 200 calls deep, presumably because it's a background thread with a smaller stack limit. Is it possible to adjust AsyncRenderer's stack limit? Or otherwise, what limits should we be aware of to prevent running into this issue? com.apple.SwiftUI.AsyncRenderer: EXC_BAD_ACCESS (code=2, address=0x16f5ebe30) #0 0x000000019c6b4460 in function signature specialization <Arg[3] = Dead> of static SwiftUI.DisplayList.ViewUpdater.Model.merge(item: inout SwiftUI.DisplayList.Item, index: SwiftUI.DisplayList.Index, into: inout SwiftUI.DisplayList.ViewUpdater.Model.State) -> SwiftUI.DisplayList.ViewUpdater.Model.MergedViewRequirements () #1 0x000000019c7c2850 in SwiftUI.DisplayList.ViewUpdater.updateInheritedViewAsync(platform: SwiftUI.DisplayList.ViewUpdater.Platform, oldItem: SwiftUI.DisplayList.Item, oldParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>, newItem: SwiftUI.DisplayList.Item, newParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>) -> Swift.Optional<SwiftUI.Time> () #2 0x000000019c7c3ef0 in SwiftUI.DisplayList.ViewUpdater.updateInheritedViewAsync(platform: SwiftUI.DisplayList.ViewUpdater.Platform, oldItem: SwiftUI.DisplayList.Item, oldParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>, newItem: SwiftUI.DisplayList.Item, newParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>) -> Swift.Optional<SwiftUI.Time> () #3 0x000000019c7c3ef0 in SwiftUI.DisplayList.ViewUpdater.updateInheritedViewAsync(platform: SwiftUI.DisplayList.ViewUpdater.Platform, oldItem: SwiftUI.DisplayList.Item, oldParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>, newItem: SwiftUI.DisplayList.Item, newParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>) -> Swift.Optional<SwiftUI.Time> () #4 0x000000019c7c3ef0 in SwiftUI.DisplayList.ViewUpdater.updateInheritedViewAsync(platform: SwiftUI.DisplayList.ViewUpdater.Platform, oldItem: SwiftUI.DisplayList.Item, oldParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>, newItem: SwiftUI.DisplayList.Item, newParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>) -> Swift.Optional<SwiftUI.Time> () ... #147 0x000000019c7c364c in SwiftUI.DisplayList.ViewUpdater.updateInheritedViewAsync(platform: SwiftUI.DisplayList.ViewUpdater.Platform, oldItem: SwiftUI.DisplayList.Item, oldParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>, newItem: SwiftUI.DisplayList.Item, newParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>) -> Swift.Optional<SwiftUI.Time> () #148 0x000000019c7c2074 in SwiftUI.DisplayList.ViewUpdater.updateAsync(platform: SwiftUI.DisplayList.ViewUpdater.Platform, oldList: SwiftUI.DisplayList, oldParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>, newList: SwiftUI.DisplayList, newParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>) -> Swift.Optional<SwiftUI.Time> () #149 0x000000019c7c1a78 in renderAsync () #150 0x000000019c60fc68 in renderDisplayList () #151 0x000000019c612094 in protocol witness for SwiftUI.ViewGraphRenderHost.renderDisplayList(_: SwiftUI.DisplayList, asynchronously: Swift.Bool, time: SwiftUI.Time, nextTime: SwiftUI.Time, targetTimestamp: Swift.Optional<SwiftUI.Time>, version: SwiftUI.DisplayList.Version, maxVersion: SwiftUI.DisplayList.Version) -> SwiftUI.Time in conformance SwiftUI.ViewGraph : SwiftUI.ViewGraphRenderHost in SwiftUI () #152 0x000000019c7c0dd0 in renderAsync () #153 0x000000019c7be6c8 in SwiftUI.ViewGraphHost.displayLinkTimer(timestamp: SwiftUI.Time, targetTimestamp: SwiftUI.Time, isAsyncThread: Swift.Bool) -> () () #154 0x000000019c7beab8 in SwiftUI.ViewGraphDisplayLink.displayLinkTimer(__C.CADisplayLink) -> () () #155 0x000000019c7be5a8 in @objc SwiftUI.ViewGraphDisplayLink.displayLinkTimer(__C.CADisplayLink) -> () () #156 0x0000000192fdbb24 in CA::Display::DisplayLinkItem::dispatch_ () #157 0x0000000192fb9164 in CA::Display::DisplayLink::dispatch_items () #158 0x0000000192f91870 in display_timer_callback () #159 0x000000019256d4cc in __CFMachPortPerform () #160 0x000000019259d0b0 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ () #161 0x000000019259cfd8 in __CFRunLoopDoSource1 () #162 0x0000000192574c1c in __CFRunLoopRun () #163 0x0000000192573a6c in _CFRunLoopRunSpecificWithOptions () #164 0x0000000190533f54 in -[NSRunLoop(NSRunLoop) runMode:beforeDate:] () #165 0x000000018fb9a51c in -[NSRunLoop(NSRunLoop) run] () #166 0x000000019c7cd5b0 in function signature specialization <Arg[1] = Dead> of static SwiftUI.ViewGraphDisplayLink.asyncThread(arg: Swift.Optional<Any>) -> () () #167 0x000000019c7cd288 in @objc static SwiftUI.ViewGraphDisplayLink.asyncThread(arg: Swift.Optional<Any>) -> () () #168 0x000000018fbf321c in __NSThread__start__ () #169 0x00000001ef0d044c in _pthread_start ()
Topic: UI Frameworks SubTopic: SwiftUI
2
1
191
Jun ’26
How to obtain an app icon regardless of current icon style?
Hey Team, Using NSWorkspace.icon(forFile:) and pointing to an app bundle, the system returns an NSImage with the icon of the app, but in the current style. For example, if the user selected tinted icons in Appearance in System Settings, then any icon I receive back from the API will be tinted using the current accent color. Is there a way to override this and get the original icon? Thanks, Ari
Topic: UI Frameworks SubTopic: AppKit
3
1
230
Jun ’26
Creating NSStatusBar.system.statusItem generates console warning
Putting: let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) at the top of AppDelegate.swift and no other code at all generates the warning below in the console when the app runs. Looks benign but it sure would be great to not have that happen. Anyone figure out how to stop this other than muting the warning? I tried all kinds of exotic deferring but that just makes the code brittle and unreadable. Here's the warning: It's not legal to call -layoutSubtreeIfNeeded on a view which is already being laid out. If you are implementing the view's -layout method, you can call -[super layout] instead. Break on void _NSDetectedLayoutRecursion(void) to debug. This will be logged only once. This may break in the future. Xcode 26.5, 26.4 - macOS 26.5.1
Topic: UI Frameworks SubTopic: AppKit
Replies
2
Boosts
0
Views
219
Activity
Jun ’26
How to animate NSSegmentedControl on macOS 26?
I noticed that in Xcode 27 Beta 1 on macOS 27 Beta 1, changing the selection of the segmented control used to switch between the Sidebar and Inspector tabs is animated. However, the standard segmented controls used by NSTabView/NSTabViewController, as well as a regular NSSegmentedControl, do not appear to have any such animation on macOS 27. I also tried using the animator proxy: segmentedControl.animator().selectedSegment = index but this did not change the behavior. How can I implement the same kind of segmented control selection animation that Xcode uses? Is there a public API for this, or is it achieved through a different mechanism?
Topic: UI Frameworks SubTopic: AppKit
Replies
1
Boosts
0
Views
218
Activity
Jun ’26
Back gesture not disabled with navigationBarBackButtonHidden(true) when using .zoom transition
[Submitted as FB22226720] For a NavigationStack destination, applying .navigationBarBackButtonHidden(true) hides the back button and also disables the interactive left-edge back gesture when using the standard push navigation transition. However, when the destination uses .navigationTransition(.zoom), the back button is hidden but the left-edge back gesture is still available—it can still be dismissed even though back is intentionally suppressed. This creates inconsistent behavior between navigation transition styles. navigationBarBackButtonHidden(_:) works with a standard push transition, but not with .navigationTransition(.zoom). In the code below, .interactiveDismissDisabled(true) is also applied as another attempt to suppress the back-swipe gesture, but it has no effect. As a result, there’s currently no clean way to prevent back navigation when using the zoom transition. REPRO STEPS Create an iOS project then replace ContentView with code below, build and run. Leave nav type set to List Push. Open an item. Verify there is no back button, then try the left-edge back gesture. Return to the root view. Change nav type to Grid Zoom. Open an item. Verify there is no back button, then try the left-edge back gesture. ACTUAL In List Push mode, the left-edge back gesture is prevented. In Grid Zoom mode, the back button is hidden, but the left-edge back gesture still works and returns to the previous view. EXPECTED Behavior should be consistent across navigation transition styles. If this configuration is meant to suppress interactive backward navigation for a destination, it should also suppress the left-edge back gesture when using .navigationTransition(.zoom). SCREEN RECORDING SAMPLE CODE struct ContentView: View { private enum NavigationMode: String, CaseIterable { case listPush = "List Push" case gridZoom = "Grid Zoom" } @Namespace private var namespace @State private var navigationMode: NavigationMode = .listPush private let colors: [Color] = [.red, .blue] var body: some View { NavigationStack { VStack(spacing: 16) { Picker("Navigation Type", selection: $navigationMode) { ForEach(NavigationMode.allCases, id: \.self) { mode in Text(mode.rawValue).tag(mode) } } .pickerStyle(.segmented) if navigationMode == .gridZoom { HStack { ForEach(colors.indices, id: \.self) { index in NavigationLink(value: index) { VStack { RoundedRectangle(cornerRadius: 14) .fill(colors[index]) .frame(height: 120) Text("Grid Item \(index + 1)") .font(.subheadline.weight(.medium)) } .padding(12) .frame(maxWidth: .infinity) .background(.quaternary.opacity(0.25), in: RoundedRectangle(cornerRadius: 16)) .matchedTransitionSource(id: index, in: namespace) } .buttonStyle(.plain) } } } else { ForEach(colors.indices, id: \.self) { index in NavigationLink(value: index) { HStack { Circle() .fill(colors[index]) .frame(width: 24, height: 24) Text("List Item \(index + 1)") Spacer() Image(systemName: "chevron.right") .foregroundStyle(.secondary) } .padding() .background(.quaternary.opacity(0.25), in: RoundedRectangle(cornerRadius: 12)) } .buttonStyle(.plain) } } Spacer() } .padding(20) .navigationTitle("Prevent Back Swipe") .navigationSubtitle("Compare Grid Zoom vs List Push") .navigationDestination(for: Int.self) { index in if navigationMode == .gridZoom { DetailView(color: colors[index]) .navigationTransition(.zoom(sourceID: index, in: namespace)) } else { DetailView(color: colors[index]) } } } } } private struct DetailView: View { @Environment(\.dismiss) private var dismiss let color: Color var body: some View { ZStack { color.ignoresSafeArea() Text("Try left-edge swipe back") .font(.title.bold()) .multilineTextAlignment(.center) .padding(.horizontal, 24) } .navigationBarBackButtonHidden(true) .interactiveDismissDisabled(true) .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Close", action: dismiss.callAsFunction) } } } }
Replies
3
Boosts
0
Views
837
Activity
Jun ’26
Am I disallowed to use Glass in the Dock in any means?
I tried Glass in NSApp.dockTile.contentView. Any Glass there isn't shown like it normally is in windows. Does this limitation exist intentionally?
Replies
1
Boosts
0
Views
174
Activity
Jun ’26
TextKit 2 + SwiftUI (NSViewRepresentable): NSTextLayoutManager rendering attributes don’t reliably draw/update
I’m embedding an NSTextView (TextKit 2) inside a SwiftUI app using NSViewRepresentable. I’m trying to highlight dynamic subranges (changing as the user types) by providing per-range rendering attributes via NSTextLayoutManager’s rendering-attributes mechanism. The issue: the highlight is unreliable. Often, the highlight doesn’t appear at all even though the delegate/data source is returning attributes for the expected range. Sometimes it appears once, but then it stops updating even when the underlying “highlight range” changes. This feels related to SwiftUI - AppKit layout issue when using NSViewRepresentable (as said in https://developer.apple.com/documentation/swiftui/nsviewrepresentable). What I’ve tried Updating the state that drives the highlight range and invalidating layout fragments / asking for relayout Ensuring all updates happen on the main thread. Calling setNeedsDisplay(_:) on the NSViewRepresentable’s underlying view. Toggling the SwiftUI view identity (e.g. .id(...)) to force reconstruction (works, but too expensive / loses state). Question In a SwiftUI + NSViewRepresentable setup with TextKit 2, what is the correct way to make NSTextLayoutManager re-query and redraw rendering attributes when my highlight ranges change? Is there a recommended invalidation call for TextKit 2 to trigger re-rendering of rendering attributes? Or is this a known limitation when hosting NSTextView inside SwiftUI, where rendering attributes aren’t reliably invalidated? If this approach is fragile, is there a better pattern for dynamic highlights that avoids mutating the attributed string (to prevent layout/scroll jitter)?
Replies
4
Boosts
0
Views
539
Activity
Jun ’26
UITextView for displaying long text?
My app displays vertically scrollable text to the user which could be as short as a single screen or as long as a book chapter: imagine something like an e-book reader which uses scrolling rather than page-turning. A long time ago when development first started, I tried using UITextView, but the size of text that could be handled was quite limited (a figure of 32767 points seems to stick in the memory). Accordingly I came up with a custom solution in which a UIScrollView handled scrolling gestures and a custom UIView rendered just the part of the text that was visible at that time. That works, but it becomes cumbersome to add support for features such as selection handles and loupes. 18 years later, is there a more smoothly integrated way of displaying long scrollable text?
Topic: UI Frameworks SubTopic: UIKit
Replies
2
Boosts
0
Views
210
Activity
Jun ’26
Debugging multi-window AppKit apps: Identifying the window associated with a breakpoint
When working on a multi-window AppKit app, how do you identify which window instance is associated with the current breakpoint? The same question applies when using LLDB. If execution stops inside an object that can exist in more than one window, such as a shared NSViewController subclass, how do you know which window’s object you are currently inspecting? Does Xcode provide a mechanism for showing the NSWindow associated with the current view, view controller or responder while debugging? My current approach is to print object identities and compare them manually. For example, if several identical windows are open, I might print the current object and its window: print(self, #function) Then I interact with one window, make a note of the printed memory addresses in the console, switch to another window and compare the output. This works, but it feels manual. I am not dealing with different window subclasses. The windows may be instances of the same class and may contain instances of the same view controller classes. I simply want an easier way to distinguish which window instance I am debugging. Is there a recommended Xcode, LLDB or AppKit workflow for this?
Replies
1
Boosts
0
Views
338
Activity
Jun ’26
Hide standard window buttons
How do I permanently hide the standard window buttons(Buttons on top left; close, minimize and zoom) In my app, I hide the standard buttons and put my own custom buttons. Some users have reported that the standard buttons appear again making the app look buggy and confuses the users At present I use following code to remove the buttons standardWindowButton(.closeButton)?.removeFromSuperview() standardWindowButton(.miniaturizeButton)?.removeFromSuperview() standardWindowButton(.zoomButton)?.removeFromSuperview() } I have to call this code from multiple places like on window initialization, when appearance changes and when the window size changes. I tried creating window without the titled stylemask, but it has other down sides like the standard window decoration is entirely skipped by the system. The resizing also is unpredictable. My question is, what is the right way to remove/hide the standard window buttons?
Topic: UI Frameworks SubTopic: AppKit
Replies
1
Boosts
0
Views
238
Activity
Jun ’26
Handling View Creation for Heterogeneous Data
In my project (an Package), I have created an Manager (can be classified as an ViewModel) that will handle state updates throughout the Package Component view: Note: The code is simplified for better understanding and to focus on principles behind things I did. The manager does complex things during state updates. public class ComponentManager: ObservedObject { @Published var rows: [any RowProtocol] = [] func updateState(_ newState: any RowProtocolData, id: String) { guard let index = rows.firstIndex(where: { $0.id == id }) else { return } rows[index].updateState(newState) } func getState(id: String) -> any RowProtocolData? { guard let index = rows.firstIndex(where: { $0.id == id }) else { return nil } return rows[index].state } } The RowProtocol is defined as follows: public protocol RowStateProtocol {} public protocol RowProtocol: Identifiable { associatedtype State: RowStateProtocol associatedtype RowView: View var id: String { get } var state: State { get } func updateState(_ newState: State) @MainActor @ViewBuilder func renderRow() -> RowView } extension RowProtocol { func updateState(_ newState: any RowProtocolData) { guard let newState = newState as? State else { return } self.updateState(newState) } } Then in Component View, I need to render the rows based on the underlying type of the row, this where the renderRow() comes in: struct ComponentView: View { @ObservedObject var manager: ComponentManager var body: some View { List { ForEach(manager.rows, id: \.id) { row in HStack { // This HStack prevent List from initing all rows due to AnyView. AnyView(row.renderRow()) } } } } } The row views will be accepting binding to the state of the row and update their state, let says we have a TextRow and a ToggleRow: struct TextRow: RowProtocol { var id: String var state: TextRowState func updateState(_ newState: TextRowState) { self.state = newState } } struct ToggleRow: RowProtocol { var id: String var state: ToggleRowState func updateState(_ newState: ToggleRowState) { self.state = newState } } In this, offcourse we cannot create an binding directly to the state of the row, since the state are through the manager and the row data won't have access to the manager. So I created an property wrapped that use the closures passed by the manager into environment to create the binding and an view that will give the binding to the content view: extenstion EnvironmentValues { @Entry internal var getState: (String) -> any RowStateProtocol? @Entry internal var updateState: (any RowStateProtocol, String) -> Void } @propertyWrapper struct RowStateBinding<State: RowStateProtocol & Equatable>: DynamicProperty { @Environment(\.getState) private var getState @Environment(\.updateState) private var updateState private let id: String init(id: String) { self.id = id } var wrappedValue: State { get { getState(id) as! State } nonmutating set { if wrappedValue != newValue { // only update for an new change, since set can be triggered for any number of reasons. updateState(newValue, id) } } } var projectedValue: Binding<State> { Binding( get: { self.wrappedValue }, set: { newValue in self.wrappedValue = newValue } ) } } struct RowStateBindingView<Content: View, State: RowStateProtocol & Equatable>: View { @RowStateBinding<State> private var state: State private let content: (Binding<State>) -> Content init(id: String, @ViewBuilder content: @escaping (Binding<State>) -> Content) { self._state = RowStateBinding(id: id) self.content = content } var body: some View { content($state) } } and in the renderRows: struct TextRowView: View { @Binding var text: TextRowState var body: some View { TextField("Enter text", text: $text.text) } } extension TextRow { func renderRow() -> some View { RowStateBindingView(id: id) { state in TextField("Enter text", text: state.text) } } } struct ToggleRowView: View { @Binding var state: ToggleRowState var body: some View { Toggle("Toggle", isOn: $state.isOn) } } extension ToggleRow { func renderRow() -> some View { RowStateBindingView(id: id) { state in Toggle("Toggle", isOn: state.isOn) } } } This way, I can adopt any view as an row view and most importantly, the view can be completely independent of the manager and used as an standalone view. Also clients of the library can create their own custom rows by just conforming to the RowProtocol and creating the view for it, without worrying about how the state management works. The manager will handle all the state updates. I prefer using stucts over classes for rows and states, since its easier to manage state updates. What do you think about this approach? Do you see any potential issues with this? Is there a better way to achieve this?
Replies
0
Boosts
0
Views
102
Activity
Jun ’26
Crash occured in UIDatePicker Calendar type
I am encountering a consistent, reproducible crash in our app when presenting a UIDatePicker configured with the calendar style. The crash triggers every single time the picker is invoked and points directly to the modern date picker's internal UICollectionView. The Exception: *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UICollectionView internal inconsistency: attempted to set layout with the collection view requiring a reload' let datePicker = UIDatePicker() datePicker.datePickerMode = .date datePicker.preferredDatePickerStyle = .compact This crash is occuring in inline style too when I try to open the calendar. I tried this in other apps. It works fine. I didn't override any collectionView layouts
Replies
1
Boosts
0
Views
130
Activity
Jun ’26
Dynamic Property inplace of onChange, task.
In the recent SwiftUI Group Lab, they mentioned using Dynamic Property instead of onChange, How to do it? Could it used as an actual property type instead of just using in combination with @propertyWrapper
Replies
0
Boosts
1
Views
143
Activity
Jun ’26
Summary of iOS/iPadOS 26 UIKit bugs related to UISearchController & UISearchBar using scope buttons
All of these issues appear when the search controller is set on the view controller's navigationItem and the search controller's searchBar has its scopeButtonTitles set. So far the following issues are affecting my app on iOS/iPadOS 26 as of beta 7: When the scopeBarActivation of UISearchController is set to .onSearchActivation, the preferredSearchBarPlacement of the navigationItem is set to .integratedButton, and the searchBarPlacementAllowsToolbarIntegration is set to false (forcing the search icon to appear in the nav bar), on both iPhones and iPads, the scope buttons never appear. They don't appear when the search is activated. They don't appear when any text is entered into the search bar. FB19771313 I attempted to work around that issue by setting the scopeBarActivation to .manual. I then show the scope bar in the didPresentSearchController delegate method and hide the scope bar in the willDismissSearchController. On an iPhone this works though the display is a bit clunky. On an iPad, the scope bar does appear via the code in didPresentSearchController, but when any scope bar button is tapped, the search controller is dismissed. This happens when the app is horizontally regular. When the app on the iPad is horizontally compact, the buttons work but the search bar's text is not correctly aligned within the search bar. Quite the mess really. I still need to post a bug report for this issue. But if issue 1 above is fixed then I don't need this workaround. When the scopeBarActivation of UISearchController is set to .onSearchActivation, the preferredSearchBarPlacement of the navigationItem is set to .stacked, and the hidesSearchBarWhenScrolling property of the navigationItem is set to false (always show the search bar), and this is all used in a UITableViewController, then upon initial display of the view controller on an iPhone or iPad, you are unable to tap on the first row of the table view except on the very bottom of the row. The currently hidden scope bar is stealing the touches. If you activate and then cancel the search (making the scope bar appear and then disappear) then you are able to tap on the first row as expected. The initially hidden scope bar also bleeds through the first row of the table. It's faint but you can tell it's not quite right. Again, this is resolved by activating and then canceling the search once. FB17888632 When the scopeBarActivation of UISearchController is set to .onSearchActivation, the preferredSearchBarPlacement of the navigationItem is set to integrated or .integratedButton, and the toolbar is shown, then on iPhones (where the search bar/icon appears in the toolbar) the scope buttons appear (at the top of the screen) the first time the search is activated. But if you cancel the search and then activate it again, the search bar never appears a second (or later) time. On an iPad the search bar/icon appears in the nav bar and you end up with the same issue as #1 above. FB17890125 Issues 3 and 4 were reported against beta 1 and still haven't been fixed. But if issue 1 is resolved on iPhone, iPad, and Mac (via Mac Catalyst), then I personally won't be affected by issues 2, 3, or 4 any more (but of course all 4 issues need to be fixed). And by resolved, I mean that the scope bar appears and disappears when it is supposed to each and every time the search is activated and cancelled (not just the first time). The scope bar doesn't interfere with touch events upon initial display of the view controller. And there are no visual glitches no matter what the horizontal size class is on an iPad. I really hope the UIKit team can get these resolved before iOS/iPadOS 26 GM.
Replies
11
Boosts
6
Views
1.9k
Activity
Jun ’26
UIView wrapper around a View
I couldn't decide whether to post this question here or in SwiftUI Q&A as there's a lot of overlaps. We're trying to create something similar to UIViewRepresentable for UIKit. This might not work for complicated cases where the View has many pieces but as long as it works for simple cases, we're happy. The only problem right now is figuring out the correct height. Currently, the height anchor is assigned to CGFloat.greatestFiniteMagnitude, which works but when inspecting the layout in View Hierarchy, it appears the wrapped view is getting stretched all the way down. Also, sometimes View Hierarchy isn't able to draw the wrapped View and I'm unsure if it's a problem of View Hierarchy or our implementation. final public class SwiftUIConfigurationContainerView<T: View>: UIView { private var contentView: UIView? public override var intrinsicContentSize: CGSize { contentView?.intrinsicContentSize ?? super.intrinsicContentSize } private var preferredContentSize: CGSize? public init(@ViewBuilder _ content: @escaping () -> T) { super.init(frame: .zero) setUpContentView(content) } @available(*, unavailable) required init?(coder: NSCoder) { return nil } private func setUpContentView(_ content: @escaping () -> T) { let contentView = UIHostingConfiguration { [weak self] in VStack(spacing: .zero) { content() .onGeometryChange(for: CGSize.self, of: \.size) { size in self?.preferredContentSize = size self?.invalidateIntrinsicContentSize() } .frame(maxWidth: .infinity, alignment: .center) Spacer(minLength: .zero) } } .minSize(width: .zero, height: .zero) .margins(.all, .zero) .makeContentView() self.contentView = contentView addSubview(contentView) contentView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ contentView.leadingAnchor.constraint(equalTo: leadingAnchor), contentView.trailingAnchor.constraint(equalTo: trailingAnchor), contentView.topAnchor.constraint(equalTo: topAnchor), contentView.heightAnchor.constraint(equalToConstant: CGFloat.greatestFiniteMagnitude), ]) } }
Replies
0
Boosts
0
Views
247
Activity
Jun ’26
How to detect backspace in SwiftUI TextField without falling back to UIViewRepresentable?
I'm building a multi-box PIN/OTP input in SwiftUI. In UIKit, I used UITextFieldDelegate to detect backspace presses on an empty field to move focus backward. SwiftUI’s .onChange(of: text) only triggers when text is actually deleted, completely missing backspaces on an already empty field. Is there a pure SwiftUI way to handle this now, or are we still forced to wrap UITextField via UIViewRepresentable?
Replies
1
Boosts
0
Views
129
Activity
Jun ’26
Source view disappearing when interrupting a zoom navigation transition
When I use the .zoom transition in a navigation stack, I get a glitch when interrupting the animation by swiping back before it completes. When doing this, the source view disappears. I can still tap it to trigger the navigation again, but its not visible on screen. This seems to be a regression in iOS 26, as it works as expected when testing on iOS 18. Has someone else seen this issue and found a workaround? Is it possible to disable interrupting the transition? Filed a feedback on the issue FB19601591 Screen recording: https://share.icloud.com/photos/04cio3fEcbR6u64PAgxuS2CLQ Example code @State var showDetail = false @Namespace var namespace var body: some View { NavigationStack { ScrollView { showDetailButton } .navigationTitle("Title") .navigationBarTitleDisplayMode(.inline) .navigationDestination(isPresented: $showDetail) { Text("Detail") .navigationTransition(.zoom(sourceID: "zoom", in: namespace)) } } } var showDetailButton: some View { Button { showDetail = true } label: { Text("Show detail") .padding() .background(.green) .matchedTransitionSource(id: "zoom", in: namespace) } } }
Topic: UI Frameworks SubTopic: SwiftUI
Replies
20
Boosts
25
Views
2.5k
Activity
Jun ’26
Programatic scroll edge effect for NSScrollView
Just like NSScrollView lets us programmatically set the contentInset in parallel to automaticallyAdjustsContentInsets, I think there should be similar functionality for blurring effect caused by scroll edge effect. I should be able programmatically set it. If the user is manually setting the contentInset then they can simply set a boolean, which when enabled will show edge effect when the scroll document goes outside the area of inset. Eg: scrollView.contentInsets = NSEdgeInsets(top: 100, left: 0, bottom: 0, right: 0) For contentInset like above set by user, they could set edge effect in two ways Automatically: scrollView.enableEdgeEffectOutsideInsets = true // This will apply edge effect based on frame size of contentInsets Programmatically: scrollView.edgeInsetEffectFrame = NSRect...
Topic: UI Frameworks SubTopic: AppKit
Replies
5
Boosts
1
Views
354
Activity
Jun ’26
Is there a better way to hide a view in a custom Layout other than placing it off-screen?
I have a custom Layout that places a number of labels for a cell footer in a certain way based on the available width that needs to conditionally hide those views that do not entirely fit anymore (based on some priorities I specify). Currently I simply move the subviews that do not fit anymore off-screen and use clipping to hide them outside the layout, as I did not find an "official" way to hide / exclude a subview from a Layout. Does anyone know a better / nicer way to do this in SwiftUI?
Topic: UI Frameworks SubTopic: SwiftUI
Replies
0
Boosts
0
Views
60
Activity
Jun ’26
about presentationDetents modifier
How do I make the sheet occupy the full screen width and bottom when I customize the height of the sheet using presentationDetents?
Replies
1
Boosts
0
Views
93
Activity
Jun ’26
AsyncRenderer stack limit
We've been getting stack overflows in code we don't control, in the background AsyncRenderer thread in a chain of calls to updateInheritedViewAsync. But the stack is less than 200 calls deep, presumably because it's a background thread with a smaller stack limit. Is it possible to adjust AsyncRenderer's stack limit? Or otherwise, what limits should we be aware of to prevent running into this issue? com.apple.SwiftUI.AsyncRenderer: EXC_BAD_ACCESS (code=2, address=0x16f5ebe30) #0 0x000000019c6b4460 in function signature specialization <Arg[3] = Dead> of static SwiftUI.DisplayList.ViewUpdater.Model.merge(item: inout SwiftUI.DisplayList.Item, index: SwiftUI.DisplayList.Index, into: inout SwiftUI.DisplayList.ViewUpdater.Model.State) -> SwiftUI.DisplayList.ViewUpdater.Model.MergedViewRequirements () #1 0x000000019c7c2850 in SwiftUI.DisplayList.ViewUpdater.updateInheritedViewAsync(platform: SwiftUI.DisplayList.ViewUpdater.Platform, oldItem: SwiftUI.DisplayList.Item, oldParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>, newItem: SwiftUI.DisplayList.Item, newParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>) -> Swift.Optional<SwiftUI.Time> () #2 0x000000019c7c3ef0 in SwiftUI.DisplayList.ViewUpdater.updateInheritedViewAsync(platform: SwiftUI.DisplayList.ViewUpdater.Platform, oldItem: SwiftUI.DisplayList.Item, oldParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>, newItem: SwiftUI.DisplayList.Item, newParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>) -> Swift.Optional<SwiftUI.Time> () #3 0x000000019c7c3ef0 in SwiftUI.DisplayList.ViewUpdater.updateInheritedViewAsync(platform: SwiftUI.DisplayList.ViewUpdater.Platform, oldItem: SwiftUI.DisplayList.Item, oldParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>, newItem: SwiftUI.DisplayList.Item, newParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>) -> Swift.Optional<SwiftUI.Time> () #4 0x000000019c7c3ef0 in SwiftUI.DisplayList.ViewUpdater.updateInheritedViewAsync(platform: SwiftUI.DisplayList.ViewUpdater.Platform, oldItem: SwiftUI.DisplayList.Item, oldParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>, newItem: SwiftUI.DisplayList.Item, newParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>) -> Swift.Optional<SwiftUI.Time> () ... #147 0x000000019c7c364c in SwiftUI.DisplayList.ViewUpdater.updateInheritedViewAsync(platform: SwiftUI.DisplayList.ViewUpdater.Platform, oldItem: SwiftUI.DisplayList.Item, oldParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>, newItem: SwiftUI.DisplayList.Item, newParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>) -> Swift.Optional<SwiftUI.Time> () #148 0x000000019c7c2074 in SwiftUI.DisplayList.ViewUpdater.updateAsync(platform: SwiftUI.DisplayList.ViewUpdater.Platform, oldList: SwiftUI.DisplayList, oldParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>, newList: SwiftUI.DisplayList, newParentState: Swift.UnsafePointer<SwiftUI.DisplayList.ViewUpdater.Model.State>) -> Swift.Optional<SwiftUI.Time> () #149 0x000000019c7c1a78 in renderAsync () #150 0x000000019c60fc68 in renderDisplayList () #151 0x000000019c612094 in protocol witness for SwiftUI.ViewGraphRenderHost.renderDisplayList(_: SwiftUI.DisplayList, asynchronously: Swift.Bool, time: SwiftUI.Time, nextTime: SwiftUI.Time, targetTimestamp: Swift.Optional<SwiftUI.Time>, version: SwiftUI.DisplayList.Version, maxVersion: SwiftUI.DisplayList.Version) -> SwiftUI.Time in conformance SwiftUI.ViewGraph : SwiftUI.ViewGraphRenderHost in SwiftUI () #152 0x000000019c7c0dd0 in renderAsync () #153 0x000000019c7be6c8 in SwiftUI.ViewGraphHost.displayLinkTimer(timestamp: SwiftUI.Time, targetTimestamp: SwiftUI.Time, isAsyncThread: Swift.Bool) -> () () #154 0x000000019c7beab8 in SwiftUI.ViewGraphDisplayLink.displayLinkTimer(__C.CADisplayLink) -> () () #155 0x000000019c7be5a8 in @objc SwiftUI.ViewGraphDisplayLink.displayLinkTimer(__C.CADisplayLink) -> () () #156 0x0000000192fdbb24 in CA::Display::DisplayLinkItem::dispatch_ () #157 0x0000000192fb9164 in CA::Display::DisplayLink::dispatch_items () #158 0x0000000192f91870 in display_timer_callback () #159 0x000000019256d4cc in __CFMachPortPerform () #160 0x000000019259d0b0 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ () #161 0x000000019259cfd8 in __CFRunLoopDoSource1 () #162 0x0000000192574c1c in __CFRunLoopRun () #163 0x0000000192573a6c in _CFRunLoopRunSpecificWithOptions () #164 0x0000000190533f54 in -[NSRunLoop(NSRunLoop) runMode:beforeDate:] () #165 0x000000018fb9a51c in -[NSRunLoop(NSRunLoop) run] () #166 0x000000019c7cd5b0 in function signature specialization <Arg[1] = Dead> of static SwiftUI.ViewGraphDisplayLink.asyncThread(arg: Swift.Optional<Any>) -> () () #167 0x000000019c7cd288 in @objc static SwiftUI.ViewGraphDisplayLink.asyncThread(arg: Swift.Optional<Any>) -> () () #168 0x000000018fbf321c in __NSThread__start__ () #169 0x00000001ef0d044c in _pthread_start ()
Topic: UI Frameworks SubTopic: SwiftUI
Replies
2
Boosts
1
Views
191
Activity
Jun ’26
How to obtain an app icon regardless of current icon style?
Hey Team, Using NSWorkspace.icon(forFile:) and pointing to an app bundle, the system returns an NSImage with the icon of the app, but in the current style. For example, if the user selected tinted icons in Appearance in System Settings, then any icon I receive back from the API will be tinted using the current accent color. Is there a way to override this and get the original icon? Thanks, Ari
Topic: UI Frameworks SubTopic: AppKit
Replies
3
Boosts
1
Views
230
Activity
Jun ’26