Issues while using struct as a binding within a view

I am currently trying to refactor some of my variables that I am using within a View into a struct for clarity. However, when I try to do this, I get a bunch of errors such as Value of type 'Binding<DrawableStaff>' has no dynamic member 'drawings' using key path from root type 'DrawableStaff'.

How do I fix these issues? I have looked into the documentation, and I have looked around online, and I haven't found a solution to this issue.

Here is what the refactored struct looks like

Code Block
struct DrawableStaff{
var drawing: Drawing = Drawing()
var drawingList: [Drawing] = [Drawing]()
var paths: [Path] = [Path]()
var PathHolder = Path()
var color = Color.primary
var lineWidth: CGFloat = 3.0
}


Here is where DrawableStaff appears in my main ContentView

Code Block
struct ContentView: View {
@State private var staff1DrawableStaff = DrawableStaff()
var body: some View {
VStack {
let staff1 = ZStack{
DrawingPad(drawableStaff: $staff1DrawableStaff)
}
}
}


Here is where DrawingPad is defined:

Code Block
struct DrawingPad: View {
@Binding var drawableStaff: DrawableStaff
var body: some View {
GeometryReader { geometry in
Path { path in
for drawing in self.drawableStaff.drawings {
self.add(drawing: drawableStaff.drawing, toPath: &path)
}
self.add(drawing: self.drawableStaff.currentDrawing, toPath: &path)
self.drawableStaff.pathHolder = path
}
.stroke(self.drawableStaff.color, lineWidth: self.drawableStaff.lineWidth)
.background(Color(UIColor.systemBackground))
.gesture(
DragGesture(minimumDistance: 0.1)
.onChanged({ (value) in
let currentPoint = value.location
if currentPoint.y >= 0
&& currentPoint.y < geometry.size.height {
self.drawableStaff.currentDrawing.points.append(currentPoint)
}
})
.onEnded({ (value) in
self.drawableStaff.drawings.append(self.currentDrawing)
self.drawableStaff.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)
            }
        }
    }
}


Here is my Drawing definition:

Code Block
struct Drawing {
    var points: [CGPoint] = [CGPoint]()
}

Could you show Drawing definitions ?
Whoops, I forgot to include Drawing!

Code Block
struct Drawing {
    var points: [CGPoint] = [CGPoint]()
}


line 8

Code Block
for drawing in self.drawableStaff.drawings {

drawings is undefined

Do you mean drawingList ?

Line 9 of DrawingPad
self is a View. How do you expect to add ?
To what object do you want to add drawing ?
Replacing self.drawableStaff.drawings with self.drawableStaff.drawingList fixes one of the errors, but I am still getting a bunch of errors related to the binding
There are a lot of inconsistencies in your code.

Lines 9, 11
Code Block
self.add(drawing …

self is a View.

To whom do you want to .add something to ?
Where is this add function defined ?

You have a
Code Block
for drawing in …

but don't use drawing in the loop.

So please correct the most obvious errors, then we'll focus on the remaining problem.
I have looked through the definition of DrawingStaff a bit, and have attempted to better make it fit with the new enum instead of the individual variables that it was previously using.

Code Block
struct DrawingPad: View {
    @Binding var drawableStaff: DrawableStaff
    var body: some View {
        GeometryReader { geometry in
            Path { path in
                for drawing in self.drawableStaff.drawingList {
                 self.add(drawing: drawing, toPath: &path)
                }
                self.add(drawing: self.drawableStaff.drawing, toPath: &path) // Call self.add()
                print(path)
                self.drawableStaff.pathHolder = path
                print("PathHolder: \(self.$drawableStaff.pathHolder)")
            }
            .stroke(self.drawableStaff.color, lineWidth: self.drawableStaff.lineWidth)
                .background(Color(UIColor.systemBackground))
                .gesture(
                    DragGesture(minimumDistance: 0.1)
                        .onChanged({ (value) in
                            let currentPoint = value.location
                            if currentPoint.y >= 0
                                && currentPoint.y < geometry.size.height {
                                self.drawableStaff.drawing.points.append(currentPoint)
                            }
                        })
                        .onEnded({ (value) in
                            self.drawableStaff.drawingList.append(self.drawableStaff.drawing)
                            self.drawableStaff.drawing = Drawing()
                        })
            )
        }
        .frame(maxHeight: .infinity)
    }

I just realized that I forgot to include the add() method in my original post.
currentDrawing is nowhere defined either.
And you did not answer about the
Code Block
for drawing in

loop

Please re read what you post.
Accepted Answer
I have solved (most) of my problems, and here is my code.

Code Block
    var body: some View {
        GeometryReader { geometry in
            Path { path in
                for drawing in self.drawableStaff.drawingList {
                    self.add(drawing: drawing, toPath: &path)
                }
                self.add(drawing: self.drawableStaff.drawing, toPath: &path)
                print("Current path: \(path)")
                self.drawableStaff.pathHolder = path
                print("PathHolder: \(self.$drawableStaff.pathHolder)")
            }
            .stroke(self.drawableStaff.color, lineWidth: self.drawableStaff.lineWidth)
                .background(Color(UIColor.systemBackground))
                .gesture(
                    DragGesture(minimumDistance: 0.1)
                        .onChanged({ (value) in
                            let currentPoint = value.location
                            if currentPoint.y >= 0
                                && currentPoint.y < geometry.size.height {
                                self.drawableStaff.drawing.points.append(currentPoint)
                            }
                        })
                        .onEnded({ (value) in
                            self.drawableStaff.drawingList.append(self.drawableStaff.drawing)
                            self.drawableStaff.drawing = Drawing()
                        })
            )
        }
        .frame(maxHeight: .infinity)
    }

I also had a typo in pathHolder in DrawableStaff where pathHolder was typed as PathHolder, which was causing line 10 issues.

This fixes the main issue, but causes a different unrelated issue.
You marked the question as closed, that means you don't have issues here ?

It is good to post the new code ; but it would have been better to answer questions raised in the different posts, as soon as you got them. We should have saved your time and ours as well.

Good continuation.
Issues while using struct as a binding within a view
 
 
Q