Post

Replies

Boosts

Views

Activity

Reply to SwiftUI on macOS equivalent of NSSavePanel for choosing a destination URL?
@DTS Engineer We used to routinely present dialogs modally before sheets were introduced around 10.6 I believe. The introduction of sheets provided a more refined user experience and were quickly adopted by both document-based applications and shoebox-based applications. As far as I know (the HIG no longer explicitly calls this out), using sheets for open and save dialogs remains the recommended user experience. panel.runModal() has its use-cases, like when selecting a document to open after the application has launched, but it doesn't seem like the right fit for many macOS use cases. If a SwiftUI-native way to request a save destination would fit your app better, that is a good thing to send through Feedback Assistant Fair enough. Given SwiftUI already has considerable APIs for fileImporter, fileExporter, fileMover and fileDialog, I assumed I was overlooking an existing API for this common macOS use case. Thanks for the discussion.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jul ’26
Reply to SwiftUI on macOS equivalent of NSSavePanel for choosing a destination URL?
@DTS Engineer Thanks for the quick follow-up. I'm pretty familiar with what you've presented. The "problem" with invoking NSSavePanel from within a SwiftUI macOS application is that you don't necessarily have access to the underlying NSWindow to properly present the NSSavePanel as a sheet, which would be the expected user experience. I'm aware of the following ways to work around this, all of which feel awkward in a pure SwiftUI environment: Assume the application's current key window is the one to use. Use an NSViewRepresentable as a "window accessor" Abandon the full SwiftUI app lifecycle and just using a traditional AppKit lifecycle for window management. Are there other ways I've overlooked that are more idiomatic SwiftUI? The ability to ask the user for a URL to save content to is such a fundamental macOS feature that it's omission genuinely perplexes me. Are you able to elaborate at all as to what the general rational and thinking is behind this?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jun ’26
Reply to How do you make a resizable segmented control in SwiftUI for macOS?
Part of the mystery has now been solved. On macOS 27, NSSegmentedControl gained a new property: var role: NSSegmentedControl.Role { get set } Setting this value to .tabs enables a glass effect during user interactions. If the control is also inside a glass container, then a glass bevel style will also be applied. This appears to mirror the SwiftUI TabsPickerStyle behaviour, with the role .valueSelection mapping to SegmentedPickerStyle. I'm still unable to get a SwiftUI Picker to "stretch to fill" and I suspect this is because NSSegmentedControl.Distribution is not exposed to SwiftUI, and likely is defaulting to .fit.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jun ’26
Reply to How do you correctly use a SwiftUI View inside an NSToolbarItem?
@galad87 In this example, the benefits of a SwiftUI Button is minimal, but not zero. Integration with an existing @Observable view model, for example, is easier with a SwiftUI button versus the target/action pattern from AppKit. Regardless, this snippet was more intended to show a minimal example I could come up with that exhibited differences between AppKit views and SwiftUI views within an NSToolbarItem. As the complexity of the hosted SwiftUI view increases, the number of "glitches" I see increases. (ex: Window dragging that initiates inside the hosted SwiftUI view does not appear to work if that SwiftUI view has a subview with a gesture of its own. Mouse events appear to get consumed by the entire NSHostingView.) Rich toolbar items like Safari's address bar or Xcode's status bar would be great candidates for SwiftUI, but my experience so far has been unsuccessful given the issues I've encountered embedding SwiftUI Views inside an NSToolbarItem. I'm curious if these are known issues and this embedding isn't fully supported, or if I'm missing some rules and requirements I need to follow given NSToolbar's quirks.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jun ’26
Reply to How do you make a resizable segmented control in SwiftUI for macOS?
Hoping to try and boost this now that macOS 27 Beta 1 is out. Xcode 27 uses segmented controls in the sidebar and inspector panels as their tabs. These segmented control have a glass effect applied to them and they stretch to fill the width of their respective container views. How do you actually create such a control? In macOS 27, using SwiftUI I can create a segmented control that has the glass effect but I cannot get it to "stretch to fill" the width. This is using .pickerStyle(.tabs), which isn't actually the same look as Xcode's but at least has some glass attributes. Using AppKit I can get the "stretch to fill" behaviour, but I cannot figure out how to get the glass effect. TL;DR: How do you make a segmented control like the on in Xcode 27's sidebar and inspector panel under macOS 27?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jun ’26
Reply to How do you disable split view tracking separators in macOS 26 Tahoe?
After further debugging, apparently that's not a tracking separator but rather the NSSplitViewControllers actual divider that is showing. This was confusing because NSWindow.titlebarAppearsTransparent = false doesn't seem to hide it. So even when the titlebar is not transparent, some underlying content is being shown. A solution we found was to use a nested NSSplitViewControllers that uses the safe layout guide for its constraints. That appears to give a full height inspector view with a "content view" that remains below the window's titlebar.
Topic: UI Frameworks SubTopic: AppKit Tags:
Mar ’26
Reply to Do SwiftUI Segmented Controls on macOS 26 support the icon and title label style?
[quote='877122022, DTS Engineer, /thread/816517?answerId=877122022#877122022'] Consider also, the Human Interface Guidelines recommends using either text or an image in a single segmented control, not a mix. [/quote] Hah, here I was drawing inspiration from Tahoe's new menu items which do encourage the use of text and an image in a label. 🤷‍♂️
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Feb ’26
Reply to Clarification on SwiftUI Environment Write Performance
[quote='865440022, Engineer, /thread/806702?answerId=865440022#865440022'] However, in your example, since those environment variables wouldn't likely update very frequently (they're not really in a hot path) the cost of putting them in the environment is probably negligible. [/quote] Indeed, and now that I know that every write to any environment variable is not as egregious as I initially thought, then I'm a bit less concerned about this issue. That said, I do want to revisit this a bit. In your demo, you were worried about writes in the hot path during a critical operation like scrolling. What I'm finding on macOS isn't that I have "hot paths" but rather I have a lot of views being updated because of a very small change. These might be infrequent, the cost is high and noticeable. An example would be keeping track of a selected objects on a canvas such that a bunch of inspector panels and other panes need to update their state based as the selection changes. Selection changes are relatively infrequent (compared to scrolling) but a when they occur, a lot of views need to be updated. In my app, such a scenario is giving the application an overall "sluggish" feel as the user clicks around. I wouldn't say that you need to go back to all your uses of environment values and change them to use @Observable classes, but if you're seeing performance issues, or building something new, it's worth considering. One big issue I have with @Observable and @Environment is that I have to use a concrete type in @Environment if I want to be able to make an @Bindable reference. Ideally, I want the environment value to be generic. I can define it as being a protocol, but then I cannot convert the protocol to an @Bindable, or at least I don't know how. Specifically, the following doesn't work: struct Item { var frame: CGRect } protocol SelectionProvider: Observable { var selectedItem: Item? { get } } @Observable final class Document: SelectionProvider { var selectedItem: Item? } extension EnvironmentValues { @Entry var selectionProvider: (any SelectionProvider)? } struct SampleView: View { @Environment(\.selectionProvider) private var selectionProvider var body: some View { // Error: 'init(wrappedValue:)' is unavailable: // The wrapped value must be an object that conforms to Observable @Bindable var selectionProvider = selectionProvider } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Nov ’25
Reply to Clarification on SwiftUI Environment Write Performance
@StevenPeterson Thanks for chiming in and thanks for the video itself, much appreciated. No, the view bodies are only run if the body uses the environment value for the key(s) used in that view and the value changes. That makes a lot more sense to me and aligns with the simple demo app I made to test out my original question. Consider: struct ContentView: View { @Environment(\.name) var name @Environment(\.age) var age var body: some View { Text(name) } } If \.name is updated anywhere, then ContentView.body will be run but if \.age is updated anywhere, then body is not run because \.age is not referenced in the body. What worried me was that if somewhere else a view wrote to \.address, then ContentView would be re-evaluated even though it doesn't refer to \.address in any way. That's how I (incorrectly) interpreted the slide above. But in SwiftUI, an update doesn't always cause the view body to run again, but there is still a cost associated with these updates. That's the real clarifying statement, for me. There's a SwiftUI concept of "updating a view" that doesn't require calling body and there's a concept of "updating a view" that does require calling body. You're saying that the cost of "updating a view even if it doesn't call body" is something that we should still consider in performance sensitive areas like scrolling. (ie: The cost is less than calling .body but it's not "zero".) Yes, look for EnvironmentWriter in Instruments, in both the lists of updates and the Cause & Effect graph. This is shown in the demos in the talk you linked. I'm quite thankful for the new SwiftUI Instrument, but I'm still learning how to correctly interpret the data it produces. With your comments and video, I'm going to revisit some of my @Environment usage and likely replace writes an @Observable object of properties I formerly wrote directly into the environment. My example above is contrived, but rather than having environment values for \.name, \.age and \.address it sounds like I should just have \.person, which is an @Observable object containing the three properties. That way, writes to any of those properties don't trigger the issue you were talking about in the video. Cheers
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Nov ’25
Reply to NSOutlineView incorrectly draws disclosure indicator when item views are SwiftUI views.
Apparently if you just wrap the NSHostingView inside an NSTableCellView without doing anything else then it works and the disclosure indicator is correctly aligned. 🤷‍♂️ final class WrappedHostingView<Content: View> : NSTableCellView { let hostingView: NSHostingView<Content> init(rootView: Content) { self.hostingView = NSHostingView(rootView: rootView) self.hostingView.translatesAutoresizingMaskIntoConstraints = false super.init(frame: .zero) self.identifier = .wrappedHostingViewIdentifier self.addSubview(hostingView) NSLayoutConstraint.activate([ hostingView.leadingAnchor.constraint(equalTo: leadingAnchor), hostingView.trailingAnchor.constraint(equalTo: trailingAnchor), hostingView.topAnchor.constraint(equalTo: topAnchor), hostingView.bottomAnchor.constraint(equalTo: bottomAnchor) ]) } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Nov ’25
Reply to Fous, FocusState and Architecture
I’ve run into a similar issue in a macOS app and ended up rethinking how to use SwiftUI’s focus system. The app has the usual triple-panel layout: sidebar, content, inspector. The content is two tables, either of which can be focused. Each table has a TableController, exposed via .focused(). The inspector reads the focused controller to update its display, and the sidebar shows its selection—both via @FocusedValue. On paper this works, but there’s a catch: when the sidebar or inspector itself gains focus (e.g. a text field), the focused table controller becomes nil. I tried various .focus modifiers but could never get the behaviour I wanted. What I really needed was a property influenced by focus but not identical to it. For example: Use the focused table controller if one exists. Otherwise fall back to the last focused table controller. Add other rules as needed. The solution was to introduce an active table controller managed by an @Observable object in the environment. The sidebar and inspector observe this active controller instead of the raw focused value. Whenever focus changes, the observable updates the active controller according to my rules. This also allows changing the active controller through other means (picker, button, etc.). In your case, you might similarly combine focused values with some key state to derive an “active” entity. If focus remains your primary driver, you still get tab-navigation, keyboard control, and accessibility “for free.” Finally, don’t forget about `.focused(_:equals:). If you need to drive focus from your controller (mapping active → focused), this modifier helps align SwiftUI focus with your active entity. Hope that helps. Good luck!
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Oct ’25
Reply to On macOS, what is the appropriate way to disable the sidebar material in a NavigationSplitView?
@DTS Engineer Unfortunately, .scrollContentBackground doesn't seem to have any affect regardless of where I place it. We don't actually use a List in our Sidebar but I tried this in a demo app and wasn't able to make it work. In our SidebarView, we use a ScrollView as the top-element, then a VStack, followed by a bunch of text fields and other standard controls. What's interesting (and desirable) with the .background(.windowColor) implementation is that it disables vibrancy for all these controls, which is actually what we want. (We're trying to avoid vibrant textfields in the sidebar with non-vibrant textfields in the inspector.) As for the "custom tab view" I alluded to, it's not a SwiftUI TabView but rather just a custom View that conditionally shows a child view. We wanted to use TabView but we couldn't figure out how to hide the native tab bar, which is possible in AppKit. (NSTabViewController.TabStyle.unspecified)
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Aug ’25
Reply to On macOS, what is the appropriate way to disable the sidebar material in a NavigationSplitView?
@szymczyk The contents of my SidebarView is a custom tab view where each tab hosts views containing different content. Refer to the sidebar or inspector panels in Xcode for a good idea. In Xcode's case, they allow vibrancy in the sidebar even for the panels that are not lists. In the Inspector, there is no vibrancy. We're hoping to disable the vibrancy in the sidebar so that it matches the look-and-feel of the inspector panel.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Aug ’25
Reply to Is NavigationSplitView on macOS 27 broken?
Following up to say that this remains broken in macOS 27 beta 3. macOS 27.0 Beta (26A5378j) Xcode 27.0 beta 3 (27A5218g) Open Xcode, File -> New Project, macOS SwiftUI app and copy paste the code above and then run.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
4w
Reply to SwiftUI on macOS equivalent of NSSavePanel for choosing a destination URL?
@DTS Engineer Feedback Assistant: FB23515927
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jul ’26
Reply to SwiftUI on macOS equivalent of NSSavePanel for choosing a destination URL?
@DTS Engineer We used to routinely present dialogs modally before sheets were introduced around 10.6 I believe. The introduction of sheets provided a more refined user experience and were quickly adopted by both document-based applications and shoebox-based applications. As far as I know (the HIG no longer explicitly calls this out), using sheets for open and save dialogs remains the recommended user experience. panel.runModal() has its use-cases, like when selecting a document to open after the application has launched, but it doesn't seem like the right fit for many macOS use cases. If a SwiftUI-native way to request a save destination would fit your app better, that is a good thing to send through Feedback Assistant Fair enough. Given SwiftUI already has considerable APIs for fileImporter, fileExporter, fileMover and fileDialog, I assumed I was overlooking an existing API for this common macOS use case. Thanks for the discussion.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jul ’26
Reply to SwiftUI on macOS equivalent of NSSavePanel for choosing a destination URL?
@DTS Engineer Thanks for the quick follow-up. I'm pretty familiar with what you've presented. The "problem" with invoking NSSavePanel from within a SwiftUI macOS application is that you don't necessarily have access to the underlying NSWindow to properly present the NSSavePanel as a sheet, which would be the expected user experience. I'm aware of the following ways to work around this, all of which feel awkward in a pure SwiftUI environment: Assume the application's current key window is the one to use. Use an NSViewRepresentable as a "window accessor" Abandon the full SwiftUI app lifecycle and just using a traditional AppKit lifecycle for window management. Are there other ways I've overlooked that are more idiomatic SwiftUI? The ability to ask the user for a URL to save content to is such a fundamental macOS feature that it's omission genuinely perplexes me. Are you able to elaborate at all as to what the general rational and thinking is behind this?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’26
Reply to How do you make a resizable segmented control in SwiftUI for macOS?
Part of the mystery has now been solved. On macOS 27, NSSegmentedControl gained a new property: var role: NSSegmentedControl.Role { get set } Setting this value to .tabs enables a glass effect during user interactions. If the control is also inside a glass container, then a glass bevel style will also be applied. This appears to mirror the SwiftUI TabsPickerStyle behaviour, with the role .valueSelection mapping to SegmentedPickerStyle. I'm still unable to get a SwiftUI Picker to "stretch to fill" and I suspect this is because NSSegmentedControl.Distribution is not exposed to SwiftUI, and likely is defaulting to .fit.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’26
Reply to How do you correctly use a SwiftUI View inside an NSToolbarItem?
@galad87 In this example, the benefits of a SwiftUI Button is minimal, but not zero. Integration with an existing @Observable view model, for example, is easier with a SwiftUI button versus the target/action pattern from AppKit. Regardless, this snippet was more intended to show a minimal example I could come up with that exhibited differences between AppKit views and SwiftUI views within an NSToolbarItem. As the complexity of the hosted SwiftUI view increases, the number of "glitches" I see increases. (ex: Window dragging that initiates inside the hosted SwiftUI view does not appear to work if that SwiftUI view has a subview with a gesture of its own. Mouse events appear to get consumed by the entire NSHostingView.) Rich toolbar items like Safari's address bar or Xcode's status bar would be great candidates for SwiftUI, but my experience so far has been unsuccessful given the issues I've encountered embedding SwiftUI Views inside an NSToolbarItem. I'm curious if these are known issues and this embedding isn't fully supported, or if I'm missing some rules and requirements I need to follow given NSToolbar's quirks.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’26
Reply to How do you make a resizable segmented control in SwiftUI for macOS?
Hoping to try and boost this now that macOS 27 Beta 1 is out. Xcode 27 uses segmented controls in the sidebar and inspector panels as their tabs. These segmented control have a glass effect applied to them and they stretch to fill the width of their respective container views. How do you actually create such a control? In macOS 27, using SwiftUI I can create a segmented control that has the glass effect but I cannot get it to "stretch to fill" the width. This is using .pickerStyle(.tabs), which isn't actually the same look as Xcode's but at least has some glass attributes. Using AppKit I can get the "stretch to fill" behaviour, but I cannot figure out how to get the glass effect. TL;DR: How do you make a segmented control like the on in Xcode 27's sidebar and inspector panel under macOS 27?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’26
Reply to How do you disable split view tracking separators in macOS 26 Tahoe?
After further debugging, apparently that's not a tracking separator but rather the NSSplitViewControllers actual divider that is showing. This was confusing because NSWindow.titlebarAppearsTransparent = false doesn't seem to hide it. So even when the titlebar is not transparent, some underlying content is being shown. A solution we found was to use a nested NSSplitViewControllers that uses the safe layout guide for its constraints. That appears to give a full height inspector view with a "content view" that remains below the window's titlebar.
Topic: UI Frameworks SubTopic: AppKit Tags:
Replies
Boosts
Views
Activity
Mar ’26
Reply to Do SwiftUI Segmented Controls on macOS 26 support the icon and title label style?
[quote='877122022, DTS Engineer, /thread/816517?answerId=877122022#877122022'] Consider also, the Human Interface Guidelines recommends using either text or an image in a single segmented control, not a mix. [/quote] Hah, here I was drawing inspiration from Tahoe's new menu items which do encourage the use of text and an image in a label. 🤷‍♂️
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Feb ’26
Reply to Clarification on SwiftUI Environment Write Performance
[quote='865440022, Engineer, /thread/806702?answerId=865440022#865440022'] However, in your example, since those environment variables wouldn't likely update very frequently (they're not really in a hot path) the cost of putting them in the environment is probably negligible. [/quote] Indeed, and now that I know that every write to any environment variable is not as egregious as I initially thought, then I'm a bit less concerned about this issue. That said, I do want to revisit this a bit. In your demo, you were worried about writes in the hot path during a critical operation like scrolling. What I'm finding on macOS isn't that I have "hot paths" but rather I have a lot of views being updated because of a very small change. These might be infrequent, the cost is high and noticeable. An example would be keeping track of a selected objects on a canvas such that a bunch of inspector panels and other panes need to update their state based as the selection changes. Selection changes are relatively infrequent (compared to scrolling) but a when they occur, a lot of views need to be updated. In my app, such a scenario is giving the application an overall "sluggish" feel as the user clicks around. I wouldn't say that you need to go back to all your uses of environment values and change them to use @Observable classes, but if you're seeing performance issues, or building something new, it's worth considering. One big issue I have with @Observable and @Environment is that I have to use a concrete type in @Environment if I want to be able to make an @Bindable reference. Ideally, I want the environment value to be generic. I can define it as being a protocol, but then I cannot convert the protocol to an @Bindable, or at least I don't know how. Specifically, the following doesn't work: struct Item { var frame: CGRect } protocol SelectionProvider: Observable { var selectedItem: Item? { get } } @Observable final class Document: SelectionProvider { var selectedItem: Item? } extension EnvironmentValues { @Entry var selectionProvider: (any SelectionProvider)? } struct SampleView: View { @Environment(\.selectionProvider) private var selectionProvider var body: some View { // Error: 'init(wrappedValue:)' is unavailable: // The wrapped value must be an object that conforms to Observable @Bindable var selectionProvider = selectionProvider } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Nov ’25
Reply to Clarification on SwiftUI Environment Write Performance
@StevenPeterson Thanks for chiming in and thanks for the video itself, much appreciated. No, the view bodies are only run if the body uses the environment value for the key(s) used in that view and the value changes. That makes a lot more sense to me and aligns with the simple demo app I made to test out my original question. Consider: struct ContentView: View { @Environment(\.name) var name @Environment(\.age) var age var body: some View { Text(name) } } If \.name is updated anywhere, then ContentView.body will be run but if \.age is updated anywhere, then body is not run because \.age is not referenced in the body. What worried me was that if somewhere else a view wrote to \.address, then ContentView would be re-evaluated even though it doesn't refer to \.address in any way. That's how I (incorrectly) interpreted the slide above. But in SwiftUI, an update doesn't always cause the view body to run again, but there is still a cost associated with these updates. That's the real clarifying statement, for me. There's a SwiftUI concept of "updating a view" that doesn't require calling body and there's a concept of "updating a view" that does require calling body. You're saying that the cost of "updating a view even if it doesn't call body" is something that we should still consider in performance sensitive areas like scrolling. (ie: The cost is less than calling .body but it's not "zero".) Yes, look for EnvironmentWriter in Instruments, in both the lists of updates and the Cause & Effect graph. This is shown in the demos in the talk you linked. I'm quite thankful for the new SwiftUI Instrument, but I'm still learning how to correctly interpret the data it produces. With your comments and video, I'm going to revisit some of my @Environment usage and likely replace writes an @Observable object of properties I formerly wrote directly into the environment. My example above is contrived, but rather than having environment values for \.name, \.age and \.address it sounds like I should just have \.person, which is an @Observable object containing the three properties. That way, writes to any of those properties don't trigger the issue you were talking about in the video. Cheers
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Nov ’25
Reply to NSOutlineView incorrectly draws disclosure indicator when item views are SwiftUI views.
Apparently if you just wrap the NSHostingView inside an NSTableCellView without doing anything else then it works and the disclosure indicator is correctly aligned. 🤷‍♂️ final class WrappedHostingView<Content: View> : NSTableCellView { let hostingView: NSHostingView<Content> init(rootView: Content) { self.hostingView = NSHostingView(rootView: rootView) self.hostingView.translatesAutoresizingMaskIntoConstraints = false super.init(frame: .zero) self.identifier = .wrappedHostingViewIdentifier self.addSubview(hostingView) NSLayoutConstraint.activate([ hostingView.leadingAnchor.constraint(equalTo: leadingAnchor), hostingView.trailingAnchor.constraint(equalTo: trailingAnchor), hostingView.topAnchor.constraint(equalTo: topAnchor), hostingView.bottomAnchor.constraint(equalTo: bottomAnchor) ]) } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Nov ’25
Reply to Fous, FocusState and Architecture
I’ve run into a similar issue in a macOS app and ended up rethinking how to use SwiftUI’s focus system. The app has the usual triple-panel layout: sidebar, content, inspector. The content is two tables, either of which can be focused. Each table has a TableController, exposed via .focused(). The inspector reads the focused controller to update its display, and the sidebar shows its selection—both via @FocusedValue. On paper this works, but there’s a catch: when the sidebar or inspector itself gains focus (e.g. a text field), the focused table controller becomes nil. I tried various .focus modifiers but could never get the behaviour I wanted. What I really needed was a property influenced by focus but not identical to it. For example: Use the focused table controller if one exists. Otherwise fall back to the last focused table controller. Add other rules as needed. The solution was to introduce an active table controller managed by an @Observable object in the environment. The sidebar and inspector observe this active controller instead of the raw focused value. Whenever focus changes, the observable updates the active controller according to my rules. This also allows changing the active controller through other means (picker, button, etc.). In your case, you might similarly combine focused values with some key state to derive an “active” entity. If focus remains your primary driver, you still get tab-navigation, keyboard control, and accessibility “for free.” Finally, don’t forget about `.focused(_:equals:). If you need to drive focus from your controller (mapping active → focused), this modifier helps align SwiftUI focus with your active entity. Hope that helps. Good luck!
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Oct ’25
Reply to On macOS, what is the appropriate way to disable the sidebar material in a NavigationSplitView?
@DTS Engineer Unfortunately, .scrollContentBackground doesn't seem to have any affect regardless of where I place it. We don't actually use a List in our Sidebar but I tried this in a demo app and wasn't able to make it work. In our SidebarView, we use a ScrollView as the top-element, then a VStack, followed by a bunch of text fields and other standard controls. What's interesting (and desirable) with the .background(.windowColor) implementation is that it disables vibrancy for all these controls, which is actually what we want. (We're trying to avoid vibrant textfields in the sidebar with non-vibrant textfields in the inspector.) As for the "custom tab view" I alluded to, it's not a SwiftUI TabView but rather just a custom View that conditionally shows a child view. We wanted to use TabView but we couldn't figure out how to hide the native tab bar, which is possible in AppKit. (NSTabViewController.TabStyle.unspecified)
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Aug ’25
Reply to On macOS, what is the appropriate way to disable the sidebar material in a NavigationSplitView?
@szymczyk The contents of my SidebarView is a custom tab view where each tab hosts views containing different content. Refer to the sidebar or inspector panels in Xcode for a good idea. In Xcode's case, they allow vibrancy in the sidebar even for the panels that are not lists. In the Inspector, there is no vibrancy. We're hoping to disable the vibrancy in the sidebar so that it matches the look-and-feel of the inspector panel.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Aug ’25