Search code examples
swiftuiviewtoolbartabbarnavigationview

How to add a view so it's between navigation toolbar and tab bar


I'm trying to add a view (a drawing canvas) so it takes up all the space between a navigation toolbar at the top and the bottom tab bar.

So far I've got what's in the below screenshot:

enter image description here

As you can see, the canvas is 'bleeding' into the navigation toolbar, and not extending all the way down to the bottom tab bar.

My code:

import SwiftUI

struct CanvasView: View {
    
    @State private var currentDrawing: Drawing = Drawing()
    @State private var drawings: [Drawing] = [Drawing]()
    @State private var colourPickerShown = false
    @State private var initialColor: Color = Color.black
    @State private var undoDisabled = true

    @Binding var colour: Color
    @Binding var image: [Drawing]
    
    @Environment(\.managedObjectContext) private var viewContext
    @FetchRequest(entity: Thing.entity(), sortDescriptors: []) var things: FetchedResults<Thing>
    
    var body: some View {
    
        NavigationView {
            DrawingPad(currentDrawing: $currentDrawing, image: $drawings, color: $initialColor, lineWidth: CGFloat(3))
            .toolbar {
                ToolbarItemGroup(placement: .navigationBarLeading) {
                    Button(action: {
                    
                    }, label: {
                        Image("searchWeb")
                            .foregroundColor(.green)
                    })
                
                    Spacer()

                    Button(action: {
        
                    }, label: {
                        Image("photoLibrary")
                            .foregroundColor(.green)
                    })
                
                    Spacer()
                
                    Button(action: {
                    
                    }, label: {
                        Image("camera")
                            .foregroundColor(.green)
                    })
                
                    Spacer()

                    Button(action: {
        
                    }, label: {
                        Image("save")
                            .foregroundColor(.green)
                    })
                    
                    Spacer()
                    
                    Button {
                        self.colourPickerShown = true
                    } label: {
                        Image("pickAColour")
                    }
                }
                ToolbarItemGroup(placement: .navigationBarTrailing) {
                    Button(action: {
                        if self.image.count > 0 {
                            self.image.removeLast()
                            undoDisabled = false
                        } else {undoDisabled = true }
                    }, label: {
                        Image("undo")
                            .foregroundColor(.green)
                    })
                    
                    Spacer()
                    
                    Button(action: {
                        self.drawings = [Drawing]()
                    }, label: {
                        Image("delete")
                            .foregroundColor(.red)
                    })
                
                    Spacer()

                    Button(action: {
        
                    }, label: {
                        Image("share")
                            .foregroundColor(.green)
                    })
                
                    Spacer()
                
                    Button(action: {
                    
                    }, label: {
                        Image("canvasSettings")
                            .foregroundColor(.green)
                    })
                }
            }
        }
        .frame(height: 200)
        .sheet(isPresented: $colourPickerShown, onDismiss: {
            self.colourPickerShown = false
        }, content: { () -> ColourPicker in
            ColourPicker(colour: self.$colour, colourPickerShown: self.$colourPickerShown)
        })
    }
}

import SwiftUI

struct DrawingPad: View {
    @Binding var currentDrawing: Drawing
    @Binding var image: [Drawing]
    @Binding var color: Color
    
    var lineWidth: CGFloat
    
    var body: some View {
        GeometryReader { geometry in
            Path { path in
                for drawing in self.image {
                    self.add(drawing: drawing, toPath: &path)
                }
                self.add(drawing: self.currentDrawing, toPath: &path)
            }
            .stroke(self.color, lineWidth: self.lineWidth)
            .background(Color(white: 0.95))
            .gesture(DragGesture(minimumDistance: 0.1)
                .onChanged({ (value) in
                    let currentPoint = value.location
                    if currentPoint.y >= 0 && currentPoint.y < geometry.size.height {
                        self.currentDrawing.points.append(currentPoint)
                    }
                })
                .onEnded({ (value) in
                    self.image.append(self.currentDrawing)
                    self.currentDrawing = Drawing()
                })
            )
        }
        .frame(maxHeight: .infinity)
    }
    
    private func add(drawing: Drawing, toPath path: inout Path) {
        let points = drawing.points
        if points.count > 1 {
            for i in 0..<points.count-1 {
                let current = points[i]
                let next = points[i+1]
                path.move(to: current)
                path.addLine(to: next)
            }
        }
    }
}

Solution

  • You are explicitly setting the frame height to 200:

    .frame(height: 200)
    

    If you remove that modifier, it will take up all available space.