WatchOS NavigationSplitView never shows detail: { }

I built a quick WatchOS app that uses an @Model to populate a List within a NavigationSplitView. After several minutes, the List displays the data which is in my CloudKit database - so far so good. Unfortunately, when I attempt to tap on any of the List items, the detail view is never displayed. Here is the ContentView:

import SwiftUI
import SwiftData

struct ContentView: View {
	@Query(sort: \Squats.date, order: .reverse) var exercises: [Squats]
	@Environment(\.modelContext) var modelContext	
	@State var selectedExercise: Squats? = nil

	var body: some View {
		if exercises.count == 0 {
			Text("CloudKit not yet loaded")
		} else {
			NavigationSplitView {
				List (exercises, selection: $selectedExercise) { ex in
					Text(ex.date.format("E, MM/dd"))
				}
			} detail: {
				Text(selectedExercise?.exercise ?? "Nothing set")
			}
			.padding()
		}
	}
}

And here is the model view:

import Foundation
import SwiftData

@Model
class Squats {
	var date: Date = Date()
	var exercise: String = ""
	
	init(date: Date, exercise: String) {
		self.date = date
		self.exercise = exercise
	}
}

I’ve tried this on a number of my in-production DBs, as well as this development-only “Squats” DB - same lack of detail view on all.

Thoughts?

  • Also, I just tried to simplify by removing the dependency upon CloudKit and instead hard-coding my array of exercises: [Squats] - but no difference. NavigationSplitView does not yet appear to work on WatchOS - using all the latest beta releases as of today (Sonoma / Xcode / iOS / WatchOS).

Add a Comment

Replies

To drive navigation using List selection on watchOS, we recommend using NavigationLink as the cells/rows in your List. Your sample will work if you replace Text(ex.date.format("E, MM/dd") with NavigationLink(value: ex) { Text(ex.date.format("E, MM/dd")) }.

To drive navigation using List selection on watchOS, we recommend using NavigationLink as the cells/rows in your List. Your sample will work if you replace Text(ex.date.format("E, MM/dd") with NavigationLink(value: ex) { Text(ex.date.format("E, MM/dd")) }.

  • Thanks for your input, and NavigationLink is the navigation pattern I've been using. But because this year's WWDC sessions • Meet watchOS 10 • Update your app for watchOS 10 • Design and build apps for watchOS 10

    all 3 promote NavigationSplitView, I wanted to update my app to reflect the modern zeitgeist.
Add a Comment

We are not telling you not to use NavigationSplitView. We are saying that the contents of your List must be navigable, and Text alone is not. You can see how to use NavigationSplitView properly in the sample code associated with one of the sessions you mention, Update your app for watchOS 10. If you download the sample code at that link and open the project in the Session 10031 > End folder in Xcode 15 beta, you will see that the List inside the NavigationSplitView contains BackyardCells. If you right-click on BackyardCell and Jump to Definition, you will see the following:

struct BackyardCell: View {
    let backyard: Backyard
    
    var body: some View {
        NavigationLink(value: backyard) {
            Group {
                Text(backyard.displayName)
                    .font(.callout)
                    .padding(.horizontal, 4)
                    .foregroundStyle(Color.primary.shadow(.drop(color: .black.opacity(0.7), radius: 2, y: 1)))
                    .padding(.vertical, 8)
                    .frame(minHeight: 85, alignment: .bottomLeading)
            }
            .frame(maxWidth: .infinity, alignment: .bottomLeading)
        }
        .listRowBackground(BackyardImage(backyard: backyard))
    }
}

As you can see, BackyardCell is Text inside a NavigationLink. The NavigationLink makes the contents of the List navigable, so the user can get to the detail view in the NavigationSplitView.

  • Ahhh - 💡 lightbulbs 💡 - Text alone is not navigable! That’s actually SUPER helpful. Thank you!

Add a Comment