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
How to Add Two or More Buttons to Annotationview: Mkannotationview
Show More Button Next to End of Text Swift
Uitableviewcell Initwithstyle:Uitableviewcellstylesubtitle Is Not Working
Wkwebview: How to Preload Multiple Urls
Swift How to Add Background Color Just Around Text in a Label
Advise Where to Store Data for iOS App
iOS How to Restart App for Changing Language Swift 4
How to Remove Single Object in Array from Multiple Matching Object
Uialertcontroller Visible Only When Viewdidappear Has Finished Its Call
Keep a View Always on Top (Don't Scroll with Keyboard) in Iqkeyboardmanager
Attempting to Segue from Objective-C to Swift Vc
How to Authorize Twitter with Swifter
How to Position UI Elements on Background Image Relative to the Image
Scaling Physics Bodies in Xcode Spritekit