I have a document-based SwiftUI app. I'd like to make a inspector sidebar like the one in Xcode.
Starting with Xcode's Document App template, I tried the following:
struct ContentView: View {
@Binding var document: DocumentTestDocument
@State var showInspector = true
var body: some View {
HSplitView {
TextEditor(text: $document.text)
if showInspector {
Text("Inspector")
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
.toolbar {
Button(action: { showInspector.toggle() }) {
Label("Toggle Inspector", systemImage: "sidebar.right")
}
}
}
}
Which yielded:
How can I extend the right sidebar to full height like in Xcode?
NavigationView
works for left-side sidebars, but I'm not sure how to do it for right-side sidebars.
Here is some stripped down code that I have used in the past. It has the look and feel that you want.
It uses a NavigationView
with .navigationViewStyle(.columns)
with essentially three panes. Also, the HiddenTitleBarWindowStyle()
is important.
The first (navigation) pane is never given any width because the second (Detail) pane is always given all of the width when there is no Inspector, or all of the width less the Inspector's width when it's present. The ToolBar needs to be broken up and have its contents placed differently depending on whether the Inspector is present or not.
@main
struct DocumentTestDocumentApp: App {
var body: some Scene {
DocumentGroup(newDocument: DocumentTestDocument()) { file in
ContentView(document: file.$document)
}
.windowStyle(HiddenTitleBarWindowStyle())
}
}
struct ContentView: View {
@Binding var document: DocumentTestDocument
@State var showInspector = true
var body: some View {
GeometryReader { window in
if showInspector {
NavigationView {
TextEditor(text: $document.text)
.frame(minWidth: showInspector ? window.size.width - 200.0 : window.size.width)
.toolbar {
LeftToolBarItems(showInspector: $showInspector)
}
Inspector()
.toolbar {
RightToolBarItems(showInspector: $showInspector)
}
}
.navigationViewStyle(.columns)
} else {
NavigationView {
TextEditor(text: $document.text)
.frame(width: window.size.width)
.toolbar {
LeftToolBarItems(showInspector: $showInspector)
RightToolBarItems(showInspector: $showInspector)
}
}
.navigationViewStyle(.columns)
}
}
}
}
struct LeftToolBarItems: ToolbarContent {
@Binding var showInspector: Bool
var body: some ToolbarContent {
ToolbarItem(content: { Text("test left toolbar stuff") } )
}
}
struct RightToolBarItems: ToolbarContent {
@Binding var showInspector: Bool
var body: some ToolbarContent {
ToolbarItem(content: { Spacer() } )
ToolbarItem(placement: .primaryAction) {
Button(action: { showInspector.toggle() }) {
Label("Toggle Inspector", systemImage: "sidebar.right")
}
}
}
}
struct Inspector: View {
var body: some View {
VStack {
Text("Inspector Top")
Spacer()
Text("Bottom")
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With