Provide views, controls, and layout structures for declaring your app's user interface using SwiftUI.

Posts under SwiftUI tag

200 Posts

Post

Replies

Boosts

Views

Activity

onGeometryChange: Assertion failed: Block was expected to execute on queue
Hello! After upgrading to Xcode 16 & Swift 6 & iOS 18 I starting receiveing strange crashes. Happens randomly in different view and pointing to onGeometryChange action block. I added DispatchQueue.main.async { in hopes it will help but it didn't. HStack { ... } .onGeometryChange(for: CGSize.self, of: \.size) { value in DispatchQueue.main.async { self.width = value.width self.height = value.height } } As far as I understand, onGeometryChange is defined as nonisolated and Swift 6 enforce thread checking for the closures, SwiftUI views are always run on the main thread. Does it mean we can not use onGeometryChange safely in swiftui? BUG IN CLIENT OF LIBDISPATCH: Assertion failed: Block was expected to execute on queue [com.apple.main-thread (0x1eacdce40)] Crashed: com.apple.SwiftUI.AsyncRenderer 0 libdispatch.dylib 0x64d8 _dispatch_assert_queue_fail + 120 1 libdispatch.dylib 0x6460 _dispatch_assert_queue_fail + 194 2 libswift_Concurrency.dylib 0x62b58 <redacted> + 284 3 Grit 0x3a57cc specialized implicit closure #1 in closure #1 in PurchaseModalOld.body.getter + 4377696204 (<compiler-generated>:4377696204) 4 SwiftUI 0x5841e0 <redacted> + 60 5 SwiftUI 0x5837f8 <redacted> + 20 6 SwiftUI 0x586b5c <redacted> + 84 7 SwiftUICore 0x68846c <redacted> + 48 8 SwiftUICore 0x686dd4 <redacted> + 16 9 SwiftUICore 0x6ecc74 <redacted> + 160 10 SwiftUICore 0x686224 <redacted> + 872 11 SwiftUICore 0x685e24 $s14AttributeGraph12StatefulRuleP7SwiftUIE15withObservation2doqd__qd__yKXE_tKlF + 72 12 SwiftUI 0x95450 <redacted> + 1392 13 SwiftUI 0x7e438 <redacted> + 32 14 AttributeGraph 0x952c AG::Graph::UpdateStack::update() + 540 15 AttributeGraph 0x90f0 AG::Graph::update_attribute(AG::data::ptr<AG::Node>, unsigned int) + 424 16 AttributeGraph 0x8cc4 AG::Subgraph::update(unsigned int) + 848 17 SwiftUICore 0x9eda58 <redacted> + 348 18 SwiftUICore 0x9edf70 <redacted> + 36 19 AttributeGraph 0x148c0 AGGraphWithMainThreadHandler + 60 20 SwiftUICore 0x9e7834 $s7SwiftUI9ViewGraphC18updateOutputsAsync2atAA11DisplayListV4list_AG7VersionV7versiontSgAA4TimeV_tF + 560 21 SwiftUICore 0x9e0fc0 $s7SwiftUI16ViewRendererHostPAAE11renderAsync8interval15targetTimestampAA4TimeVSgSd_AItF + 524 22 SwiftUI 0xecfdfc <redacted> + 220 23 SwiftUI 0x55c84 <redacted> + 312 24 SwiftUI 0x55b20 <redacted> + 60 25 QuartzCore 0xc7078 <redacted> + 48 26 QuartzCore 0xc52b4 <redacted> + 884 27 QuartzCore 0xc5cb4 <redacted> + 456 28 CoreFoundation 0x555dc <redacted> + 176 29 CoreFoundation 0x55518 <redacted> + 60 30 CoreFoundation 0x55438 <redacted> + 524 31 CoreFoundation 0x54284 <redacted> + 2248 32 CoreFoundation 0x535b8 CFRunLoopRunSpecific + 572 33 Foundation 0xb6f00 <redacted> + 212 34 Foundation 0xb6dd4 <redacted> + 64 35 SwiftUI 0x38bc80 <redacted> + 792 36 SwiftUI 0x1395d0 <redacted> + 72 37 Foundation 0xc8058 <redacted> + 724 38 libsystem_pthread.dylib 0x637c _pthread_start + 136 39 libsystem_pthread.dylib 0x1494 thread_start + 8
3
0
1.1k
Mar ’25
Lazy init of @State objects using new Observable protocol
Hi, Previously, we would conform model objects to the ObservableObject protocol and use the @StateObject property wrapper when storing them to an owned binding in a View. Now, if I understand correctly, it is recommended that we use the new @Observable macro/protocol in place of ObservableObject and use the @State property wrapper rather than @StateObject. This is my understanding from documentation articles such as Migrating from the Observable Object protocol to the Observable macro. However, the StateObject property wrapper has an initialiser which takes an autoclosure parameter: extension StateObject { public init(wrappedValue thunk: @autoclosure @escaping () -> ObjectType) } This is an extremely important initialiser for state objects that are expensive to allocate. As far as I can tell, the @State property wrapper lacks an equivalent initialiser. What is the recommended migration strategy for objects which made use of this on StateObject? Thanks
3
0
361
Mar ’25
How to Programmatically Simulate a Button Tap in SwiftUI?
In UIKit, certain events like a button tap can be simulated using: button.sendActions(for: .touchUpInside) This allows us to trigger the button’s action programmatically. However, in SwiftUI, there is no direct equivalent of sendActions(for:) for views like Button. What is the recommended approach to programmatically simulate a SwiftUI button tap and trigger its action? Is there an alternative mechanism to achieve this(and for other events under UIControl.event) , especially in scenarios where we want to test interactions or trigger actions without direct user input?
1
0
369
Mar ’25
SwiftUI SimultaneousGesture with RotateGesture and MagnifyGesture fails if only one gesture is recognized
I'm trying to combine a RotateGesture and a MagnifyGesture within a single SwiftUI view using SimultaneousGesture. My goal is to allow users to rotate and zoom an image (potentially at the same time). However, I’m running into a problem: If only one gesture (say, the magnification) starts and finishes without triggering the other (rotation), it seems that the rotation gesture is considered "failed." After that, no further .onChanged or .onEnded callbacks fire for either gesture until the user lifts their fingers and starts over. Here’s a simplified version of my code: struct ImageDragView: View { @State private var scale: CGFloat = 1.0 @State private var lastScale: CGFloat = 1.0 @State private var angle: Angle = .zero @State private var lastAngle: Angle = .zero var body: some View { Image("Stickers3") .resizable() .aspectRatio(contentMode: .fit) .frame(height: 100) .rotationEffect(angle, anchor: .center) .scaleEffect(scale) .gesture(combinedGesture) } var combinedGesture: some Gesture { SimultaneousGesture( RotateGesture(minimumAngleDelta: .degrees(8)), MagnifyGesture() ) .onChanged { combinedValue in if let magnification = combinedValue.second?.magnification { let minScale = 0.2 let maxScale = 5.0 let newScale = magnification * lastScale scale = max(min(newScale, maxScale), minScale) } if let rotation = combinedValue.first?.rotation { angle = rotation + lastAngle } } .onEnded { _ in lastScale = scale lastAngle = angle } } } If I pinch and rotate together (or just rotate), both gestures work as expected. But if I only pinch (or, sometimes, if the rotation amount doesn’t meet minimumAngleDelta), subsequent gestures don’t trigger the .onChanged or .onEnded callbacks anymore, as if the entire gesture sequence is canceled. I found that setting minimumAngleDelta: .degrees(0) helps because then rotation almost never fails. But I’d like to understand why this happens and whether there’s a recommended way to handle the situation where one gesture might be recognized but not the other, without losing the gesture recognition session entirely. Is there a known workaround or best practice for combining a pinch and rotate gesture where either one might occur independently, but we still want both gestures to remain active? Any insights would be much appreciated!
1
0
246
Mar ’25
NSHostingController menu not activated
I'm attempting to write a macOS version of https://stackoverflow.com/a/74935849/2178159. From my understanding, I should be able to set the menu property of an NSResponder and it will automatically show on right click. I've tried a couple things: A: set menu on an NSHostingController's view - when I do this and right or ctrl click, nothing happens. B: set menu on NSHostingController directly - when I do this I get a crash Abstract method -[NSResponder setMenu:] called from class _TtGC7SwiftUI19NSHostingControllerGVS_21_ViewModifier_...__. Subclasses must override C: manually call NSMenu.popup in a custom subclasses of NSHostingController or NSView's rightMouseDown method - nothing happens. extension View { func contextMenu(menu: NSMenu) -> some View { modifier(ContextMenuViewModifier(menu: menu)) } } struct ContextMenuViewModifier: ViewModifier { let menu: NSMenu func body(content: Content) -> some View { Interaction_UI( view: { content }, menu: menu ) .fixedSize() } } private struct Interaction_UI<Content: View>: NSViewRepresentable { typealias NSViewType = NSView @ViewBuilder var view: Content let menu: NSMenu func makeNSView(context: Context) -> NSView { let v = NSHostingController(rootView: view) // option A - no effect v.view.menu = menu // option B - crash v.menu = menu return v.view } func updateNSView(_ nsView: NSViewType, context: Context) { // part of option A nsView.menu = menu } }
0
0
220
Mar ’25
VisionOS hands replacement inside an Immersive Space
Still don't understand why no one is clarifying about this Apple Video https://developer.apple.com/videos/play/wwdc2023/10111 At the end of this video, there's an incomplete tutorial about connecting a USDZ with mesh and Skeleton structure to the hand tracking system. No example project is linked, and no one is giving the community any clarification. Please can you help us to understand how to proceed?
4
0
508
Mar ’25
Control Widget SF image cannot stably display
I'm working on the control widget which should display the SF image on the UI, but I have found that it cannot be displayed stably. I have three ExampleControlWidget which is about the type egA egB and egC, it should all be showed but now they only show the text and placeholder. I'm aware of the images should be SF image and I can see them to show perfectly sometimes, but in other time it is just failed. This's really confused me, can anyone help me out? public enum ControlWidgetType: Sendable { case egA case egB case egC public var imageName: String { switch self { case .egA: return "egA" case .egB: return "egB" case .egC: return "egC" } } } struct ExampleControlWidget: ControlWidget { var body: some ControlWidgetConfiguration { AppIntentControlConfiguration( kind: kind, provider: Provider() ) { example in ControlWidgetToggle( example.name, isOn: example.state.isOn, action: ExampleControlWidgetIntent(id: example.id), valueLabel: { isOn in ExampleControlWidgetView( statusText: isOn ? Localization.on.text : Localization.off.text, bundle: bundle, widgetType: .egA //or .egB .egC ) .symbolEffect(.pulse) } ) .disabled(example.state.isDisabled) } .promptsForUserConfiguration() } } public struct ExampleControlWidgetView: View { private let statusText: String private let bundle: Bundle private var widgetType: ControlWidgetType = .egA public init(statusText: String, bundle: Bundle, widgetType: ControlWidgetType) { self.statusText = statusText self.bundle = bundle self.widgetType = widgetType } public var body: some View { Label( statusText, image: .init( name: widgetType.imageName, // the SF Symbol image id bundled in the Widget extension bundle: bundle ) ) } } This is the normal display: These are the display that do not show properly: The results has no rules at all, I have tried to completely uninstall the APP and reinstall but the result is same.
2
0
256
Mar ’25
Crash When Previewing w/ Struct Binding Reassignment In Constructor
Platform Specs: Xcode 16.2 Swift 6.0.3 iOS 18.2 + iOS Simulator 18.3.1 Issue: Refer to the following code: struct CustomView: View { @Binding var prop: CustomStruct init(prop p: Binding<CustomStruct>) { _prop = p } init(isPreview: Bool) { let p = CustomStruct() _prop = .constant(p) } var body: some View { VStack { Text("hi") } } } #Preview { CustomView(isPreview: true) .preferredColorScheme(.dark) } The first constructor is for normal app functionality (and previews/functions correctly when used with the rest of the app in the ContentView preview tab). The second constructor is for previewing only CustomView in its own preview tab. This constructor does not work when previewing in the same file, as shown above. It triggers an ambiguous crash, stating that the diagnostic log (which obviously provides no clear information) should be checked. I have isolated the issue to be in the Binding reassignment in the second constructor. Replacing CustomStruct with anything but another struct, like an enum or primitive, fixes the issue. Note: This bug only occurs when previewing (either through the #Preview macro or PreviewProvider struct).
2
0
288
Mar ’25
Animating Text foregroundStyle with gradients
Hello! We can animate Text color via foregroundStyle very nicely in SwiftUI like so: Text("Some text here") .foregroundStyle(boolValue ? Color.green : Color.blue) withAnimation { boolValue.toggle() } However, if the foregroundStyle is a gradient, the color of the Text view changes immediately without animation. The code below works to animate a gradient foregroundStyle on an SF Symbol, but it does not work when applied to a Text view. Is it possible to animate a Text view foregroundStyle between gradient values? Image(systemName: "pencil.circle.fill") .foregroundStyle(boolValue ? .linearGradient(colors: [.red, .orange], startPoint: .top, endPoint: .bottom) : .linearGradient(colors: [.green, .blue], startPoint: .top, endPoint: .bottom)) Thanks for your help!
1
0
305
Mar ’25
iOS App Crashes with SIGABRT and XCTest.framework Not Loaded (Xcode 16.2, SwiftUI 6)
Hello Apple Developer Community, I’m experiencing an issue with my iOS app, "WaterReminder," where it builds successfully in Xcode 16.2 but crashes immediately upon launch in the iPhone 16 Pro Simulator running iOS 18.3.1. The crash is accompanied by a "Thread 1: signal SIGABRT" error, and the Xcode console logs indicate a dyld error related to XCTest.framework/XCTest not being loaded. I’ve tried several troubleshooting steps, but the issue persists, and I’d appreciate any guidance or insights from the community. Here are the details: Environment: Xcode Version: 16.2 Simulator: iPhone 16 Pro, iOS 18.3.1 App: WaterReminder (written in SwiftUI 6) Build Configuration: Debug Issue Description: The app builds without errors, but when I run it in the iPhone 16 Pro Simulator, it shows a white screen and crashes with a SIGABRT signal. The Xcode debugger highlights the issue in the main function or app delegate, and the console logs show the following error: dyld[7358]: Library not loaded: @rpath/XCTest.framework/XCTest Referenced from: <549B4D71-6B6A-314B-86BE-95035926310E> /Users/faytek/Library/Developer/CoreSimulator/Devices/2A51383F-D8EA-4750-AE22-4CDE745164CE/data/Containers/Bundle/Application/56D8B44F-6613-4756-89F0-CB33991F0821/WaterReminder.app/WaterReminder.debug.dylib Reason: tried: '/Users/faytek/Library/Developer/Xcode/DerivedData/WaterReminder-cahqrulxghamvyclxaozotzrbsiz/Build/Products/Debug-iphonesimulator/XCTest.framework/XCTest' (no such file), '/Users/faytek/Library/Developer/CoreSimulator/Devices/2A51383F-D8EA-4750-AE22-4CDE745164CE/data/Containers/Bundle/Application/56D8B44F-6613-4756-89F0-CB33991F0821/WaterReminder.app/Frameworks/XCTest.framework/XCTest' (no such file), '/Users/faytek/Library/Developer/CoreSimulator/Devices/2A51383F-D8EA-4750-AE22-4CDE745164CE/data/Containers/Bundle/Application/56D8B44F-6613-4756-89F0-CB33991F0821/WaterReminder.app/XCTest.framework/XCTest' (no such file), '/Users/faytek/Library/Developer/CoreSimulator/Devices/2A51383F-D8EA-4750-AE22-4CDE745164CE/data/Containers/Bundle/Application/56D8B44F-6613-4756-89F0-CB33991F0821/WaterReminder.app/Frameworks/XCTest.framework/XCTest' (no such file), '/Users/faytek/Library/Developer/CoreSimulator/Devices/2A51383F-D8EA-4750-AE22-4CDE745164CE/data/Containers/Bundle/Application/56D8B44F-6613-4756-89F0-CB33991F0821/WaterReminder.app/XCTest.framework/XCTest' (no such file), '/Users/faytek/Library/Developer/CoreSimulator/Devices/2A51383F-D8EA-4750-AE22-4CDE745164CE/data/Containers/Bundle/Application/56D8B44F-6613-4756-89F0-CB33991F0821/WaterReminder.app/Frameworks/XCTest.framework/XCTest' (no such file), '/Library/Developer/CoreSimulator/Volumes/iOS_22D8075/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.3.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/XCTest.framework/XCTest' (no such file) What I’ve Tried: ◦ Verified that FBSnapshotTestCase is correctly added to the "Embed Frameworks" build phase. ◦ Confirmed that the Framework Search Paths in build settings point to the correct location. ◦ Ensured that all required frameworks are available in the dependencies folder. ◦ Cleaned the build folder (Shift + Option + Command + K) and rebuilt the project. ◦ Checked the target configuration to ensure XCTest.framework isn’t incorrectly linked to the main app target (it’s only in test targets). ◦ Updated Xcode and the iOS Simulator to the latest versions. ◦ Reset the simulator content and settings. Despite these steps, the app continues to crash with the same dyld error and SIGABRT signal. I suspect there might be an issue with how XCTest.framework is being referenced or loaded in the simulator, possibly related to using SwiftUI 6, but I’m unsure how to resolve it. Could anyone provide advice on why XCTest.framework is being referenced in my main app (since it’s not intentionally linked there) or suggest additional troubleshooting steps? I’d also appreciate any known issues or workarounds specific to Xcode 16.2, iOS 18.3.1, and SwiftUI 6. Thank you in advance for your help! Best regards, Faycel
1
0
572
Mar ’25
`.refreshable(action:)` `s indicator will not dismiss after when app into backgound (iOS 17.1)
Hello, I am encountering an issue with .refreshable(action:) in ScrollView. The refresh action works as expected when performing a pull-to-refresh. However, if I put the app in the background while the refresh operation is in progress, the refresh indicator remains visible on the screen when I return to the foreground and does not disappear. Once I interact with the ScrollView after returning to the foreground, the refresh indicator disappears, and the functionality itself is not affected. I initially attempted to resolve this issue by triggering a view redraw when scenePhase changes. However, since my app presents the SwiftUI view using UIHostingController, the scenePhase from the environment does not seem to function correctly. This issue occurs on iOS 17.1 but does not appear on iOS 16.1.1. Is there a known way to resolve this unexpected behavior? Below is a simplified sample code (some parts are omitted): struct MyView: View { @StateObject private var model: MyModel var body: some View { ScrollView { // My ContentViews... } .refreshable { do { try await self.model.refresh() } catch { // Handle error } } } } @MainActor final class MyModel: ObservableObject { // === Some Code === func refresh() async throws { let data = try await self.fetchData() self.data = Array(OrderedSet(data)) } } I apologize for any mistakes in my English, as I am using a translation tool. Thank you in advance for your help! Best regards,
1
0
176
Mar ’25
Infinite loop refreshing view with EnvironmentValue
Adding environment value openURL or dismiss to a View in a NavigationStack, without even using it, causes an infinite refresh loop. What doesn't work: a) struct ViewA: View { @State private var path = NavigationPath() var body: some View { NavigationStack(path: $path) { ViewB() } } } struct ViewB: View { @Environment(\.openURL) var openURL var body: some View { NavigationLink("Next", value: 1) .navigationDestination(for: Int.self, destination: itemView) } func itemView(_ item: Int) -> some View { Text("Item \(item)") } } Prints ViewB: _openURL changed. infinitely. b) Passing the path to ViewB and appending the value with a Button What works: a) .navigationDestination(for: Int.self) { Text("Item \($0)") } Prints ViewB: @self, @identity, _openURL changed. ViewB: @self, _openURL changed. ViewB: _openURL changed. (3 times) b) Handling the destination on ViewA, which is not ideal for my use case. Prints ViewB: @self, @identity, _openURL changed. ViewB: _openURL changed. (5 times) While the workaround would work, it is still unclear how the environment value can cause the freeze (and eventual crash). Also that passing a function as parameter fails, while providing the destination in place does not. The code is stripped down to the minimal reproducible version. Any thoughts?
3
9
929
Mar ’25
NavigationSplitView sidebar animation lag with minimum width
Hi, when I run NavigationSplitView as shown below, the sidebar opens and closes smoothly. struct TestingView: View { var body: some View { NavigationSplitView { Text("Sidebar") } detail: { Text("Detail") } } } However, when I add a minimum width, the sidebar animation starts to lag. I tried various wapping solutions, but I couldn’t get rid of the stutter. struct TestingView: View { var body: some View { NavigationSplitView { Text("Sidebar") } detail: { Text("Detail") } .frame(minWidth: 800) } } As a solution, I had to disable the animation completely: .animation(nil, value: columnVisibility) Is there a way to keep the animation without the stuttering?
2
0
322
Mar ’25
SwiftUI Gestures prevent subview gesture when build with XCode 16 in iOS 18
I have a view with some buttons, and add 2 gestures using simultaneously. My app works well when built with XCode less than 16, or run on iOS less than 18.0. Example code is below: VStack(spacing: 0) { Button { print("button tapped") } label: { Rectangle() .foregroundColor(.red) } .frame(height: 100) } .gesture( DragGesture(minimumDistance: 0) .onEnded { value in print("single tap") } .simultaneously(with: TapGesture(count: 2).onEnded { print("double tap") } ) ) .frame(width: 200, height: 200) .border(Color.purple) I expect the action on Button should be recognized and print out button tapped, but only single tap and double tap are recognized
0
1
270
Mar ’25
How To Change Animation Speed while it is running in RealityView
I have a USDZ 3d model contains a running man animation and I manage to run the model well using this code: import SwiftUI import RealityKit struct ContentView: View { @State var animationResource: AnimationResource? @State var animationDefinition: AnimationDefinition? @State var manPlayer = Entity() @State var speed:Float = 0.5 var body: some View { VStack { RealityView { content in if let item = try? await Entity(named: "run.usdz") { manPlayer = item content.add(manPlayer) } } HStack { Button(action: playThis) { Text("Play") } Button(action: increaseSpeed) { Text("increase Speed (+) ") } Button(action: decreaseSpeed) { Text("decrease Speed (-) ") } } } } func playThis() { animationResource = manPlayer.availableAnimations[0] animationDefinition = animationResource?.definition animationDefinition?.repeatMode = .repeat animationDefinition?.speed = speed // i could not add the definition to the animation resource back again // so i generated a new one let animRes = try! AnimationResource.generate(with: animationDefinition!) manPlayer.playAnimation(animRes) } func increaseSpeed() { speed += 0.1 animationDefinition?.speed = speed // Now i wonder is this the best way to increase speed // isn't it as if im adding more load to the memory // by adding another players let animRes = try! AnimationResource.generate(with: animationDefinition!) manPlayer.playAnimation(animRes) } func decreaseSpeed() { speed -= 0.1 animationDefinition?.speed = speed // Now i wonder is this the best way to increase speed // isn't it as if im adding more load to the memory // by adding another players let animRes = try! AnimationResource.generate(with: animationDefinition!) manPlayer.playAnimation(animRes) } } how to control speed of this animation while it is running without have to regenerate a resource and replay the animation over and over with every speed change knowing that every time the animation replayed it started from the frame zero meaning its not completing its cycle before its replayed but cut in the middle and start over again from start which I do not prefer to be happen. The USDZ file is here if you wish to try https://www.worldhotelity.com/stack/run.usdz
1
0
326
Mar ’25
Invalid Numeric Value (NaN) Error in SwiftUI's TextField on Long-Press
I'm experiencing a peculiar issue with SwiftUI's TextField. Whenever I long-press on the TextField, the console outputs an error about passing an invalid numeric value (NaN, or not-a-number) to the CoreGraphics API. This issue persists even in a new Xcode project with minimal code. Code Snippet: import SwiftUI struct ContentView: View { @State private var text: String = "" var body: some View { TextField("Placeholder", text: $text) } } Error: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number) to CoreGraphics API and this value is being ignored. Please fix this problem. Steps to Reproduce: Create a new SwiftUI project in Xcode. Add a TextField to the ContentView. Run the app on a device or simulator. Long-press inside the TextField. What I've Tried: Updating to the latest version of Xcode and iOS. Using UIViewRepresentable to wrap a UIKit UITextField. Creating a new Xcode project to isolate the issue. None of these steps have resolved the issue. Questions: Has anyone else encountered this problem? Are there any known workarounds for this issue? Is this a known bug, and if so, has it been addressed in any updates?
21
34
13k
Mar ’25
MacOS: Spacing between NavigationLink-s in a sidebar with NavigationView.
How can I put one list item at the top and another one at the bottom, retaining the NavigationView functionality? Here is a simple app: struct ContentView: View { var body: some View { NavigationView { Sidebar() } } } struct Sidebar: View { @State private var isActive = true var body: some View { List { NavigationLink(isActive: $isActive) { HomeView() } label: { Text("Home") } NavigationLink { SettingsView() } label: { Text("Settings") } } } } struct HomeView: View { var body: some View { VStack {} .navigationTitle("Home") } } struct SettingsView: View { var body: some View { VStack {} .navigationTitle("Settings") } } Which looks like this: My initial though was to put a Spacer() between each NavigationLink, but it results in an unexpected view: What i can do: Place an empty VStack between each NavigationLink with a hard-coded height like this: VStack {}.frame(height: 275) Which looks like this: But it wouldn't work if a user would want to increase the height of a window. I could disable window resizing which is kind of fine, but not the most optimal. Another obvious option was to replace the List with a VStack, but with this approach the styling of the NavigationLink gets broken and it does not get highlighted when I click on it. It looks like this: P.S. I know that NavigationView is deprecated, but i want to support macOS 12.0.
1
0
310
Mar ’25