I have four files. In PKCanvasRepresentation.swift I only initialise the canvas view. In CanvasView.swift I use the initialisation and want to assign the individual tools through the given selection from NoteToolbarView.swift. In NoteToolbarView I build an overview of buttons that should be used to select the tools. And finally, I merge CanvasView and NoteToolbarView into NoteView.swift. My problem is that I have not yet found a way to pass the selection from NoteToolbarView.swift to CanvasView.swift.
import SwiftUI
import PencilKit
struct PKCanvasRepresentation: UIViewRepresentable {
@Binding var canvasView: PKCanvasView
func makeUIView(context: Context) -> PKCanvasView {
canvasView.isOpaque = false
canvasView.tool = PKInkingTool(.pen, color: .black, width: 5)
canvasView.drawingPolicy = .anyInput
return canvasView
}
func updateUIView(_ uiView: PKCanvasView, context: Context) {
}
}
import SwiftUI
import PencilKit
struct CanvasView: View {
@State private var canvasView = PKCanvasView()
@Binding private var selectedTool: String
public init(selectedTool: Binding<String>) {
self._selectedTool = selectedTool
}
var body: some View {
ZStack {
Color.white
PKCanvasRepresentation(canvasView: $canvasView)
.padding(.all, 20)
.background(Color.mint)
}
.onAppear {
setTool()
}
}
func setTool() {
switch selectedTool {
case "pen":
canvasView.tool = PKInkingTool(.pen, color: .black, width: 5)
case "eraser":
canvasView.tool = PKEraserTool(.vector)
default :
canvasView.tool = PKInkingTool(.pen, color: .red, width: 5)
}
}
}
struct CanvasView_Previews: PreviewProvider {
static var previews: some View {
CanvasView(selectedTool: .constant("pen"))
}
}
import SwiftUI
import PencilKit
struct NoteToolbarView: View {
@Environment(\.presentationMode) var presentationMode
@Binding var selectedTool: String
@State private var pencilPressed = false
@State private var eraserPressed = false
@State private var settingPressed = false
@State private var eraserImage = "eraser"
@State private var pencilWeight: Font.Weight = .medium
@State private var eraserWeight: Font.Weight = .medium
@State private var settingWeight: Font.Weight = .medium
var body: some View {
VStack(alignment: .leading) {
HStack(alignment: .center) {
Button {
reset(trigger: "default")
presentationMode.wrappedValue.dismiss()
} label: {
Image(systemName: "arrowshape.turn.up.left")
}
Button(action: {
if pencilPressed {
PencilSecondPressed()
} else {
PencilFirstPressed()
reset(trigger: "pencil")
selectedTool = "pen"
}
}) {
Image(systemName: "applepencil")
.fontWeight(pencilWeight)
}
Button(action: {
if eraserPressed {
PencilSecondPressed()
} else {
PencilFirstPressed()
reset(trigger: "eraser")
selectedTool = "eraser"
}
}) {
Image(systemName: eraserImage)
.fontWeight(eraserWeight)
}
Text("Notes")
.frame(maxWidth: .infinity, alignment: .center)
Button(action: {
if settingPressed {
PencilSecondPressed()
} else {
PencilFirstPressed()
reset(trigger: "setting")
}
}) {
Image(systemName: "doc.badge.plus")
.fontWeight(settingWeight)
.frame( alignment: .trailing)
}
Button(action: {
if settingPressed {
PencilSecondPressed()
} else {
PencilFirstPressed()
reset(trigger: "setting")
}
}) {
Image(systemName: "list.dash")
.fontWeight(settingWeight)
.frame( alignment: .trailing)
}
}
.frame(height: 40)
.foregroundColor(Color.green)
.padding(.leading, 30)
.padding(.trailing, 30)
.imageScale(.large)
Divider()
}
}
func reset(trigger: String) {
switch trigger {
case "pencil" :
pencilWeight = .black
pencilPressed = true
eraserImage = "eraser"
eraserWeight = .medium
eraserPressed = false
settingWeight = .medium
settingPressed = false
case "eraser" :
pencilWeight = .medium
pencilPressed = false
eraserImage = "eraser.fill"
eraserWeight = .black
eraserPressed = true
settingWeight = .medium
settingPressed = false
case "setting" :
pencilWeight = .medium
pencilPressed = false
eraserImage = "eraser"
eraserWeight = .medium
eraserPressed = false
settingWeight = .black
settingPressed = true
default:
pencilWeight = .medium
pencilPressed = false
eraserImage = "eraser"
eraserWeight = .medium
eraserPressed = false
settingWeight = .medium
settingPressed = false
}
}
func PencilFirstPressed() {
print("first time")
}
func PencilSecondPressed() {
print("second time")
}
}
struct NoteToolbarView_Previews: PreviewProvider {
static var previews: some View {
NoteToolbarView(selectedTool: .constant("p"))
}
}
import SwiftUI
import PencilKit
struct NoteView: View {
@State private var selectedTool: String = "pen"
@State private var screenWidth: CGFloat = UIScreen.main.bounds.width
var body: some View {
VStack {
NoteToolbarView(selectedTool: $selectedTool)
.frame(height: 40)
CanvasView(selectedTool: $selectedTool)
.frame(width: screenWidth - 60)
.padding(.all, 30)
}
}
}
struct NoteView_Previews: PreviewProvider {
static var previews: some View {
NoteView()
}
}
I have to admit that I haven't found a proper guide to the PencilKit and I haven't been in the world of Swift programming that long. I have tried a few times to help myself with ChatGpt but this did not really get me very far.
One had to use the update function of the PKCanvasView