After a lot of trial and error, and gaining a deeper understanding of how NavigationSplitView, NavigationStack, and NavigationPath can work together, I came up with the following solution, that allows me to push a list onto an existing one, and use NavigationSplitView's detail: to push a detail. While this doesn't support recursive-lists (more than two levels deep), that's not a requirement for my usage.
The "trick" that I learned that allowed this to work, was to use NavigationPath within a NavigationStack in my NavigationSplitView sidebar, in order to push another list onto the detail.
In addition, the trigger of detail: in a NavigationSplitView is from the List(selection:) within the side-bar.
Because I am using the same Binding within both my List and its sub-list, the NavigationSplitView pushes the detail onto the highest stack.
Here's the final result. working on iPhone and iPad:
In order to push a LocationListView onto an existing one, I incorporated NavigationPath:
ContentView
struct ContentView: View {
@State private var navigationPath = NavigationPath()
@State private var selectedItem: Location?
@State private var columnVisibility = NavigationSplitViewVisibility.doubleColumn
var body: some View {
NavigationSplitView(columnVisibility: $columnVisibility) {
NavigationStack(path: $navigationPath) {
LocationListView(
locationData: LocationSampleData(
locations: LocationSampleData.sampleLocations,
locationGroups: LocationSampleData.sampleLocationGroups
), selectedItem: $selectedItem,
navigationPath: $navigationPath)
.navigationDestination(for: LocationGroup.self) { locationGroup in
LocationListView(
locationData: LocationSampleData(locations: locationGroup.locations), selectedItem: $selectedItem,
navigationPath: $navigationPath
)
}
}
} detail: {
if let selectedItem = selectedItem {
LocationDetailView(selectedLocation: selectedItem)
}
}
}
}
LocationListView
struct LocationListView: View {
var locationData: LocationSampleData
@Binding var selectedItem: Location?
@Binding var navigationPath: NavigationPath
var body: some View {
List(selection: $selectedItem) {
if let locations = locationData.locations {
ForEach(locations) { location in
NavigationLink(value: location) {
Text(location.name)
.bold()
}
}
}
if let locationGroups = locationData.locationGroups {
ForEach(locationGroups) { locationGroup in
Button(action: {
navigationPath.append(locationGroup)
}) {
Text(locationGroup.name)
.bold()
.foregroundStyle(.red)
}
}
}
}
.navigationTitle("Saturday Spots")
.navigationBarTitleDisplayMode(.large)
}
}
Post
Replies
Boosts
Views
Activity
I'm having the same thing, does anyone know why it's not appearing?
How can I determine that my subscription is working properly in production if I'm not using a server and App Store Connect doesn't show subscription information?
It seems you have a good understanding of the different UI elements. Like you said, you would use two UITextFields in order to allow the user to input their username/password.
In order to directly answer your first question:
There is no standard way of implementing a login screen in an app, but here is a link to many examples of some:
pttrns.com/?scid=17
Most of the time there’s no need to create a new window for this, in general you shouldn’t have interaction with the app’s window.
Lastly, it is important to note that if you are implementing a sign up/log in system, and it will have social media login options, you must comply with App Store Review Guideline 4.8: https://developer.apple.com/app-store/review/guidelines/#sign-in-with-apple