Post

Replies

Boosts

Views

Activity

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:
1w
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:
1w
Reply to How do you compute backing pixel alignment in SwiftUI's `Layout`?
Stumbled across: EnvironmentValues - displayScale EnvironmentValues - pixelLength I suppose I can pass these into the custom Layout object for use during subview placement. Still curious if there's any way to tell SwiftUI or Layout to always use backing aligned coordinates instead of having to calculate them all by hand (which I've oddly never seen mentioned in any documentation or videos).
Topic: UI Frameworks SubTopic: SwiftUI Tags:
1w
Reply to In SwiftUI for macOS, how can you detect if a view or any ancestor is "hidden"?
@pilotcoder Yeah, I would normally agree to remove the expensive view. On macOS, I find that some "state" can be lost when that happens. (ex: the scroll position in a table, the viewport in a map, the current position in a video player, etc...) You could create @State variables for as many of those properties as you can (assuming they are accessible), but at least in AppKit where it's possible to hold on to views that have already been created, it's a nice feature to also know if the view is hidden or not.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
1w
Reply to How can I connect NSTableCellView.textField to a SwiftUI view?
You can't directly assign NSHostingView to the textField property of NSTableCellView because it expects an NSTextField, and a hosting view is a NSView object. I'm aware of that. The pseudo code above was trying to ask how I could connect a property or view from rootView to either the cell's textField or the imageView. Instead, you could use your hosting view as the cell and include a text field and image either as a Label or LabeledContent If I create a SwiftUI View who's body consists of a Label and assign that SwiftUI view to the rootView of an NSHostingView which I return from the NSOutlineView's delegate (in place of returning an NSTableCellView), the NSOutlineView does not recognize the Label as the textField in the same way it does in AppKit. Specifically, changes to the "Sidebar Icon Size" in the Settings app are not reflected in this SwiftUI view. The size of the label's text and image do not automatically update, as they do in AppKit. Creating a SwiftUI cell view and then populating it with an NSTextField and an NSImageView kind of defeats the purpose of using SwiftUI here. I might as well just use an NSTableCellView, no?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
2w
Reply to On macOS, how do you place a toolbar item on the trailing edge of the window's toolbar when an Inspector view is open?
macOS Tahoe 26 Beta 4 does, somewhat, fix the problem but it also introduces a new set of problems. Namely: The Sidebar icon is now trailing-aligned instead of leading align, which means the Sidebar icon now moves as the sidebar is toggled. The tracking separator for the inspector view is now ignored. Toolbar items that are leading of the separator under Sequoia are now flush-trailing with the Inspector toolbar item on Tahoe. See the attached screenshots comparing the two. The Sequoia screenshot was compiled under Xcode 16 running on Sequois. The Tahoe screenshot was compiled under Xcode 26b4 running on Tahoe. In both cases the Minimum Deployment is set to macOS 15.5. Note the difference in positions between the toolbar items. The toolbar code is the "original" implementation, whereby .toolbar and all ToolbarItems are attached to the NavigationSplitView.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Aug ’25
Reply to On macOS, how do you place a toolbar item on the trailing edge of the window's toolbar when an Inspector view is open?
Turns out if you accidentally move the toolbar from being on the NavigationSplitView to being on the InspectorContentView then you get the behaviour I was looking for. .inspector(isPresented: $isInspectorPresented) { InspectorContentView() .toolbar { ToolbarItem { Spacer() } ToolbarItem(placement: .primaryAction) { Button { isInspectorPresented.toggle() } label: { Label("Toggle Inspector", systemImage: "sidebar.right") } } } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Aug ’25
Reply to Application crashes when using TextEditor(text, selection)
Similar experience on macOS. Using TextSelection with a TextEditor is very unstable and crashes quite easily, especially if the selection is used to mutate the string bound to the TextEditor. (Which is common for operations that involve replacing the selected text.) In Xcode, the following error is reporting in the console: Swift/StringUTF16View.swift:372: Fatal error: String index is out of bounds The full call stack is pasted below For any SwiftUI developers reading this: Unscientifically, it feels like this happens much more frequently in an AppKit application hosting a TextEditor than it does inside a SwiftUI application. If I make a demo SwiftUI app with nothing more than a ContentView and a TextEditor, then it's harder to trigger this bug (but not impossible, as I just did it). On the other hand, when used inside a much larger AppKit app, it happens quite easily even though the actual SwiftUI code isn't that different. 🤷‍♂️ Xcode Version 16.3 (16E140), macOS 15.4.1 (24E263)
Topic: UI Frameworks SubTopic: SwiftUI Tags:
May ’25
Reply to How to effectively use task(id:) when multiple properties are involved?
Follow Up Awhile back there was a discussion on Swift Forum that proposed creating an EquatableBox to solve this problem. That solution leverages parameters packs. I've since adapted that and created a View modifier along the following lines. So far it seems to be working as expected, though I can't help but think I've overlooked something. extension View { /// task(ids:) /// func task<each T: Equatable>( ids: repeat each T, priority: TaskPriority = .userInitiated, _ action: @escaping @Sendable () async -> Void ) -> some View { task( id: EquatablePack(repeat each ids), priority: priority, action ) } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
May ’25
Reply to How to hide the tab bar in SwiftUI's TabView for macOS?
[quote='839309022, DTS Engineer, /thread/784248?answerId=839309022#839309022'] We suggest using native UI elements [/quote] Are you suggesting that I forgo using SwiftUI's TabView and instead use NSTabView from AppKit? I'm currently using NSTabViewController but was hoping to reduce my dependencies on AppKit and adopt SwiftUI as much as possible. We suggest using native UI elements, but you could hide the Toolbar with .toolbar(.hidden). That seems to hide the window's toolbar. I'm trying to hide the tab bar as presented by TabView on macOS, which I presume is using NSTabView. As noted above, NSTabViewController allows you to hide the tab bar and NSTabView itself offers NSTabPosition.None. However, I'm unable to configure those withTabView and thus, on macOS, I'm left with the default "Aqua-style" tab bar, which I don't want.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
May ’25
Reply to How do you restore a Sheet's window frame in SwiftUI for macOS
[quote='838899022, DTS Engineer, /thread/783804?answerId=838899022#838899022'] Are you referring to Sheet or windows? [/quote] Well, in AppKit I can present an NSViewController as a sheet via NSViewController.presentViewControllerAsSheet or I can present an NSWindow via NSWindow.beginSheet... When using NSWindow, I have easy access to NSWindow.frameAutosaveName which, if set before the NSWindow is presented as a sheet, will restore it's size. If I use NSViewController, I have to grab the window in something like viewWillAppear, but that does work. In the end, I ended up a bridged solution that does the following: Embeds the SwiftUI view that should be presented as a sheet inside an NSHostingController. Create a new NSWindow with the hosting controller as the contentViewController. Configure the NSWindow as appropriate and then present as a sheet through AppKit. It took quite awhile to get it right, but in the end the secret sauce was setting NSHostingController.sizingOptions to .intrinsicContentSize. There's still an issue with NSWindow resizing when its contentViewController is set, but I think that's been an AppKit issue for awhile. It's more reliable to just add the view to the NSWindow's contentView instead, otherwise the NSWindow resizes to the initial size of the hosting controller. But for now, it appears to be working. I suspect I'm pushing my luck a little bit because the actual view hierarchy is: NSWindow.contentViewController -> NSHostingController NSHostingController -> NSViewControllerRepresentable NSViewControllerRepresentable -> NSSplitViewController NSSplitViewItems -> SwiftUI Views VSplitView and HSplitView don't appear to remember their positions at all. NSSplitViewController does, hence the need to use it instead. But NSSplitViewController's splitViewItems were wreaking havoc with a resizable sheet. Intrinsic content size appears to have resolved that issue. Ultimately, it's three SwiftUI views hosted inside an NSSplitViewController which is presented as a resizable sheet.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
May ’25
Reply to Should you access @State properties from an NSViewController (AppKit / SwiftUI Integration)?
Great, that's kind of what I was expecting. So a shared ViewModel like in the implementation below is the recommended way to marshal data between an NSViewController and a SwiftUI View? import AppKit import SwiftUI final class ViewModel: ObservableObject { @Published var details: String = "" } struct DetailsView: View { @ObservedObject var viewModel: ViewModel var body: some View { Text(viewModel.details) } } final class ViewController: NSViewController { private let viewModel: ViewModel init() { self.viewModel = ViewModel() super.init(nibName: nil, bundle: nil) } override func viewDidLoad() { let detailsView = DetailsView(viewModel: viewModel) view.addSubview(NSHostingView(rootView:detailsView)) } func updateDetails(_ details: String) { viewModel.details = details } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Apr ’25
Reply to Predictive code completion download failed
Same problem here. Updated to macOS 15.1 today and then downloaded Xcode 16.1 (16B40). On launch, Xcode attempted to download the predictive code model but failed. Also fails when download is invoked from Xcode - Settings - Downloads. This is the first attempt at downloading Xcode's predictive code model. Prior to today, laptop was running macOS 14. The operation couldn’t be completed. (ModelCatalog.CatalogErrors.AssetErrors error 1.) Domain: ModelCatalog.CatalogErrors.AssetErrors Code: 1 User Info: { DVTErrorCreationDateKey = "2024-10-28 20:15:42 +0000"; } -- Failed to find asset: com.apple.fm.code.generate_small_v1.tokenizer - no asset Domain: ModelCatalog.CatalogErrors.AssetErrors Code: 1 -- System Information macOS Version 15.1 (Build 24B83) Xcode 16.1 (23503) (Build 16B40) Timestamp: 2024-10-28T16:15:42-04:00
Oct ’24