0

I have a Core Data Project that has 2 entities

Drawing (one to many relationship with Frame)

Frame - has an attribute called canvasDrawing that holds data of a PKDrawing.

When I am trying to switch frames (because this is an animation app): 1st, the drawing layers itself in the first of the array that holds the frames 2nd, I can never see any other more frames apart from the first frame in the array.

struct DrawingView: View {
    @Environment(\.managedObjectContext) var viewContext

    @State var id:UUID?
    @State private var data:Data?
    @State var title:String?
    @State var canvas: Drawing
    @State private var selectedFrame: Int = 0
    @State private var frames: [Frame] = []

    var body: some View {
        VStack{
            if frames.isEmpty {
                DrawingCanvasView(data: Data(), id: canvas.id!, frames: frames, frameIndex: $selectedFrame, canvas: canvas)
                    .environment(\.managedObjectContext, viewContext)
            } else {
                DrawingCanvasView(data: frames[selectedFrame].canvasData ?? Data(), id: canvas.id!, frames: frames, frameIndex: $selectedFrame, canvas: canvas)
                    .environment(\.managedObjectContext, viewContext)
            }


            HStack {
                ForEach(frames.indices, id: \.self) { frame in
                    Button {
                        if selectedFrame != frame  {
                            selectedFrame = frame
                        }

                    } label: {
                            Image(systemName: "photo")
                            Text(String(frame + 1))
                    }
                    .padding()
                    Divider()
                }

                // Add Frame
                Button {
                    let frame = Frame(context: viewContext)
                    frame.duration = 1
                    frame.canvasData = Data()

                    canvas.addToFrames(frame)

                    do {
                        try viewContext.save()
                    } catch {
                        print(error)
                    }

                    frames.append(frame)


                } label: {
                    Image(systemName: "plus")
                }

            }
            .frame(height: 50)
        }
        .task {
            let newArray = canvas.frames?.allObjects as! [Frame]
            frames = newArray
        }
        .onChange(of: selectedFrame) { newValue in
            DrawingCanvasViewController().drawingData = Data()
            DrawingCanvasViewController().drawingData = frames[newValue].canvasData!
        }
    }
}

DrawingCanvasView:

struct DrawingCanvasView: UIViewControllerRepresentable {
    @Environment(\.managedObjectContext) private var viewContext

    @State var data: Data
    @State var id: UUID
    @State var frames: [Frame]
    @Binding var frameIndex: Int
    @State var canvas: Drawing

    func updateUIViewController(_ uiViewController: DrawingCanvasViewController, context: Context) {
        uiViewController.drawingData = data
    }

    typealias UIViewControllerType = DrawingCanvasViewController



    func makeUIViewController(context: Context) -> DrawingCanvasViewController {
        let viewController = DrawingCanvasViewController()

        viewController.drawingData = data
        viewController.drawingChanged = { data in
            let request: NSFetchRequest<Drawing> = Drawing.fetchRequest()
            let predicate = NSPredicate(format: "id == %@", id as CVarArg)
            request.predicate = predicate
            do {
                let result = try viewContext.fetch(request)
                if let drawing = result.first {

                    guard frameIndex < drawing.frames?.count ?? 0 else {
                        print("Invalid frame index")
                        return
                    }

                    if let framesArray = drawing.frames?.allObjects as? [Frame] {
                        let frameToUpdate = framesArray[frameIndex]
                        frameToUpdate.canvasData = data
                        do {
                            try viewContext.save()
                        } catch {
                            print(error)
                        }

                        print("Updated data at index: \(frameIndex)")

                    }
                }
            } catch {
                print(error)
            }
        }
        return viewController
    }
}

Finally, DrawingCanvasViewController:

class DrawingCanvasViewController: UIViewController {

    lazy var canvas: PKCanvasView = {
        let view = PKCanvasView()
        view.drawingPolicy = .anyInput
        view.minimumZoomScale = 1
        view.maximumZoomScale = 1
        view.translatesAutoresizingMaskIntoConstraints = false

        return view
    }()
    var drawingData = Data()
    var drawingChanged: (Data) -> Void = {_ in}

    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(canvas)
        NSLayoutConstraint.activate([
                                        canvas.leadingAnchor.constraint(equalTo: view.leadingAnchor),
                                        canvas.trailingAnchor.constraint(equalTo: view.trailingAnchor),
                                        canvas.topAnchor.constraint(equalTo: view.topAnchor),
                                        canvas.bottomAnchor.constraint(equalTo: view.bottomAnchor)])
        canvas.delegate = self
        canvas.becomeFirstResponder()
        if let drawing = try? PKDrawing(data: drawingData){
            canvas.drawing = drawing
        }
    }
}

I can confirm that in the makeUI function of the DrawingCanvasView, it is saving to the right index, but I cannot see that frame (at that index) in the DrawingView.

It is probably a lot to read, but please any suggestions are greatly appreciated, I am not sure where I am going wrong.

anish1
  • 27
  • 6

0 Answers0