Swift: How to Change Detailview Depending on Sidebar Selection State with Swiftui 4

Swift: How to change DetailView depending on SideBar Selection State with SwiftUI 4?

It looks like they forgot (or got broken) ViewBuilder for detail: part. It worth submitting feedback to Apple.

A safe workaround is to wrap conditional block into some stack, like

    } detail: {
VStack { // << here !!
if let safeNavigationItem = navigationItem {
safeNavigationItem.rootView
} else {
Text(String(localized: "select.an.option", defaultValue: "Select an Option"))
}
}
}

Tested with Xcode 14b3 / iOS 16

SwiftUI NavigationSplitView - reset Detail view when Sidebar selection changes

You should be able to add an .onChange modifier:

.onChange(of: selectedContent) { _ in 
selectedDetail = nil
}

SwiftUI sidebar list does not register first click

It is needed to add selection for List, like below

@State var current = Set<String>()
var body: some View {
List(items, id: \.self, selection: $current) { item in
NavigationLink(destination: DetailView(selection: item)) {
Text(item)
}
}
.listStyle(SidebarListStyle())
}

How do I handle selection in NavigationView on macOS correctly?

After finding the tutorial from Apple it became clear that you don't use NavigiationLink on macOS. Instead you bind the list and add two views to NavigationView.

With these updates to MainView and DetailView my example works perfectly:

struct DetailView: View {
@Binding var content: DetailContent?
@EnvironmentObject var navigationRouter: NavigationRouter

var body: some View {
VStack {
Text("\(content?.rawValue ?? -1)")
Button(action: { self.navigationRouter.selection = DetailContent.allCases.randomElement()!}) {
Text("Take me anywhere")
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}

struct MainView: View {
@ObservedObject var navigationRouter = NavigationRouter()
@State var detailContent: DetailContent?

var body: some View {
NavigationView {
List(selection: $detailContent) {
Section(header: Text("Section")) {
ForEach(DetailContent.allCases) { item in
Text("\(item.rawValue)")
.tag(item)
}
}
}
.frame(minWidth: 250, maxWidth: 350)
.listStyle(SidebarListStyle())
DetailView(content: $detailContent)
}
.environmentObject(navigationRouter)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.onReceive(navigationRouter.$selection) { output in
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(200)) {
self.detailContent = output
}
}
}
}


Related Topics



Leave a reply



Submit