Reputation: 589
OUTLINE
I have made a custom slimline sidebar that I am now implementing across the whole app. The sidebar consists of a main button that is always showing and when pressed it shows or hides the rest of the sidebar that consists of buttons navigating to other views.
I am currently implementing the sidebar across the app on each view by creating a ZStack
like this:
struct MainView: View {
var body: some View {
ZStack(alignment: .topLeading) {
SideBarCustom()
Text("Hello, World!")
}
}
}
PROBLEM
I am planning on adding a GeometryReader
so if the side bar is shown the rest of the content moves over. With this in mind, the way I am implementing the sidebar on every view feels clunky and a long winded way to add it. Is there a more simple/better method to add this to each view?
Sidebar Code:
struct SideBarCustom: View {
@State var isToggle = false
var names = ["Home", "Products", "Compare", "AR", "Search"]
var icons = ["house.fill", "printer.fill.and.paper.fill", "list.bullet.rectangle", "arkit", "magnifyingglass"]
var imgSize = 20
var body: some View {
GeometryReader { geo in
VStack {
Button(action: {
self.isToggle.toggle()
}, label: {
Image("hexagons")
.resizable()
.frame(width: 40, height: 40)
.padding(.bottom, 20)
})
if isToggle {
ZStack{
RoundedRectangle(cornerRadius: 5)
.foregroundColor(Color.red)
.frame(width: 70, height: geo.size.height)
VStack(alignment: .center, spacing: 60) {
ForEach(Array(zip(names, icons)), id: \.0) { item in
Button(action: {
// NAVIIGATE TO VIEW
}, label: {
VStack {
Image(systemName: item.1)
.resizable()
.frame(width: CGFloat(imgSize), height: CGFloat(imgSize))
Text(item.0)
}
})
}
}
}
}
}
}
}
}
Upvotes: 0
Views: 902
Reputation: 52347
I don't think there's necessarily a reason to use GeometryReader
here. The following is an example that has a dynamic width sidebar (although you could set it to a fixed value) that slides in and out. The main content view resizes itself automatically, since it's in an HStack
:
struct ContentView : View {
@State private var sidebarShown = false
var body: some View {
HStack {
if sidebarShown {
CustomSidebar(sidebarShown: $sidebarShown)
.frame(maxHeight: .infinity)
.border(Color.red)
.transition(sidebarShown ? .move(edge: .leading) : .move(edge: .trailing) )
}
ZStack(alignment: .topLeading) {
MainContentView()
.frame(maxWidth: .infinity, maxHeight: .infinity)
if !sidebarShown {
Button(action: {
withAnimation {
sidebarShown.toggle()
}
}) {
Image(systemName: "info.circle")
}
}
}
}
}
}
struct CustomSidebar : View {
@Binding var sidebarShown : Bool
var body: some View {
VStack {
Button(action: {
withAnimation {
sidebarShown.toggle()
}
}) {
Image(systemName: "info.circle")
}
Spacer()
Text("Hi")
Text("There")
Text("World")
Spacer()
}
}
}
struct MainContentView: View {
var body: some View {
VStack {
Text("Main content")
}
}
}
Upvotes: 1