ios – Tips on how to resize a Sticky Observe correctly?

ios – Tips on how to resize a Sticky Observe correctly?


I am at the moment attempting out a small notice app. I wish to add a sticky notice to the drawing pad. I would like to have the ability to transfer and resize the sticky notice.
Transferring already works, however altering the scale doesn’t work in a managed manner. Are you able to assist me with this? Both it would not work in any respect to alter the scale, or it adjustments fully uncontrolled. Right here is the code

import SwiftUI
import PencilKit

struct NotesView: View {
    @State non-public var canvasView = PKCanvasView()
    @State non-public var toolPicker = PKToolPicker()
    @State non-public var isToolPickerVisible = false
    @State non-public var stickyNotes: [StickyNoteView] = [] // Array für die Sticky Notes
    @State non-public var selectedColor: Coloration = .yellow // Standardfarbe für Sticky Notes

    var physique: some View {
        VStack {
            // Werkzeugleiste mit zusätzlichen Optionen
            HStack {
                Button(motion: toggleToolPicker) {
                    Picture(systemName: isToolPickerVisible ? "pencil.circle.fill" : "pencil.circle")
                }
                Button(motion: createStickyNote) {
                    Picture(systemName: "notice.textual content")
                }
                Button(motion: addShape) {
                    Picture(systemName: "sq..on.circle")
                }
                Button(motion: addTextField) {
                    Picture(systemName: "textformat")
                }
                Button(motion: addPhoto) {
                    Picture(systemName: "picture")
                }
                Button(motion: undoLastAction) {
                    Picture(systemName: "arrow.uturn.backward")
                }
                Menu {
                    // Farbauswahl für Sticky Notes
                    Button(motion: { selectedColor = .yellow }) {
                        Textual content("Gelb")
                        Picture(systemName: "circle.fill").foregroundColor(.yellow)
                    }
                    Button(motion: { selectedColor = .inexperienced }) {
                        Textual content("Grün")
                        Picture(systemName: "circle.fill").foregroundColor(.inexperienced)
                    }
                    Button(motion: { selectedColor = .blue }) {
                        Textual content("Blau")
                        Picture(systemName: "circle.fill").foregroundColor(.blue)
                    }
                    Button(motion: { selectedColor = .pink }) {
                        Textual content("Pink")
                        Picture(systemName: "circle.fill").foregroundColor(.pink)
                    }
                } label: {
                    Label("Farbe", systemImage: "paintpalette")
                }
            }

            // Zeichenfläche (Canvas) für das Zeichnen
            ZStack {
                PKCanvasRepresentable(canvasView: $canvasView)
                    .onAppear {
                        toolPicker.setVisible(isToolPickerVisible, forFirstResponder: canvasView)
                        toolPicker.addObserver(canvasView)
                        canvasView.becomeFirstResponder() // Setze die Canvas als First Responder
                    }
                    .onChange(of: isToolPickerVisible) { newValue in
                        toolPicker.setVisible(newValue, forFirstResponder: canvasView)
                        if newValue {
                            canvasView.becomeFirstResponder()
                        }
                    }
                    .gesture(DragGesture(minimumDistance: 0).onChanged { _ in
                        // Werkzeugleiste aktivieren, wenn der Apple Pencil benutzt wird
                        if !isToolPickerVisible {
                            isToolPickerVisible = true
                            toolPicker.setVisible(true, forFirstResponder: canvasView)
                        }
                    })

                // Sticky Observe-Ansicht auf der Zeichenfläche hinzufügen
                ForEach(stickyNotes) { stickyNote in
                    stickyNote
                }
            }
        }
    }

    // Sichtbarkeit des Werkzeugpickers umschalten und das Image ändern
    func toggleToolPicker() {
        isToolPickerVisible.toggle()
        toolPicker.setVisible(isToolPickerVisible, forFirstResponder: canvasView)
    }

    // Sticky Observe erstellen und zur Liste hinzufügen
    func createStickyNote() {
        let newStickyNote = StickyNoteView(shade: selectedColor) // Verwende die ausgewählte Farbe
        stickyNotes.append(newStickyNote)
    }

    func addShape() {
        // Funktion, um eine Type hinzuzufügen
    }

    func addTextField() {
        // Funktion, um ein Textfeld hinzuzufügen
    }

    func addPhoto() {
        // Funktion, um ein Foto hinzuzufügen
    }

    func undoLastAction() {
        canvasView.undoManager?.undo()
    }
}

// Canvas-Representable zum Verbinden von UIKit's PKCanvasView mit SwiftUI
struct PKCanvasRepresentable: UIViewRepresentable {
    @Binding var canvasView: PKCanvasView

    func makeUIView(context: Context) -> PKCanvasView {
        return canvasView
    }

    func updateUIView(_ uiView: PKCanvasView, context: Context) {
        // Aktualisiere die Canvas-Ansicht falls nötig
    }
}

struct StickyNoteView: View, Identifiable {
    let id = UUID()
    @State non-public var place: CGSize = .zero // Place der Sticky Observe
    @State non-public var lastPosition: CGSize = .zero // Letzte bekannte Place
    @State non-public var textual content: String = "" // Inhalt der Sticky Observe
    @State non-public var dimension: CGSize = CGSize(width: 200, top: 200) // Größe der Sticky Observe
    @State non-public var isSelected: Bool = false // Ob die Sticky Observe ausgewählt ist
    @State non-public var isResizing: Bool = false // Ob gerade eine Größenänderung durchgeführt wird
    @State non-public var lastSize: CGSize = CGSize(width: 200, top: 200) // Letzte Größe
    let shade: Coloration

    var physique: some View {
        ZStack(alignment: .topLeading) {
            // Sticky Observe Hintergrund
            shade
                .body(width: dimension.width, top: dimension.top)
                .cornerRadius(10)
                .overlay(
                    RoundedRectangle(cornerRadius: 10)
                        .stroke(isSelected ? Coloration.blue : Coloration.clear, lineWidth: 3) // Markierungsrahmen, wenn ausgewählt
                )
                .overlay(
                    // Resize-Griffe nur anzeigen, wenn die Sticky Observe ausgewählt ist
                    isSelected ? resizeHandles : nil, alignment: .bottomTrailing
                )

            // Textfeld innerhalb der Sticky Observe
            TextField("Notiz", textual content: $textual content)
                .padding()
                .background(Coloration.clear)
                .body(width: dimension.width - 20, top: dimension.top - 20)
                .multilineTextAlignment(.main)
                .disabled(!isSelected) // Nur bei Auswahl kann geschrieben werden

        }
        .offset(x: place.width, y: place.top) // Place der Sticky Observe
        .gesture(
            DragGesture()
                .onChanged { worth in
                    // Sticky Observe verschieben, wenn nicht resized wird
                    if !isResizing {
                        self.place = CGSize(width: lastPosition.width + worth.translation.width,
                                               top: lastPosition.top + worth.translation.top)
                    }
                }
                .onEnded { _ in
                    self.lastPosition = self.place
                }
        )
        .onTapGesture {
            // Sticky Observe auswählen oder abwählen
            isSelected.toggle()
        }
    }

    // Resize-Griffe an allen Ecken und Seiten
    var resizeHandles: some View {
        Group {
            resizeHandle(place: .bottomRight)
            resizeHandle(place: .bottomLeft)
            resizeHandle(place: .topRight)
            resizeHandle(place: .topLeft)
            resizeHandle(place: .left)
            resizeHandle(place: .proper)
            resizeHandle(place: .high)
            resizeHandle(place: .backside)
        }
    }

    // Einzelne Resize-Griffe basierend auf der Place
    func resizeHandle(place: ResizePosition) -> some View {
        ZStack {
            Circle()
                .fill(Coloration.blue) // Blau gefüllte Resize-Griffe
                .body(width: 10, top: 10) // Kleinere Griffe
                .gesture(
                    DragGesture()
                        .onChanged { worth in
                            change place {
                            case .bottomRight:
                                self.dimension.width = max(100, lastSize.width + worth.translation.width)
                                self.dimension.top = max(100, lastSize.top + worth.translation.top)
                            case .bottomLeft:
                                self.dimension.width = max(100, lastSize.width - worth.translation.width)
                                self.dimension.top = max(100, lastSize.top + worth.translation.top)
                                self.place.width = lastPosition.width + worth.translation.width
                            case .topRight:
                                self.dimension.width = max(100, lastSize.width + worth.translation.width)
                                self.dimension.top = max(100, lastSize.top - worth.translation.top)
                                self.place.top = lastPosition.top + worth.translation.top
                            case .topLeft:
                                self.dimension.width = max(100, lastSize.width - worth.translation.width)
                                self.dimension.top = max(100, lastSize.top - worth.translation.top)
                                self.place = CGSize(width: lastPosition.width + worth.translation.width, top: lastPosition.top + worth.translation.top)
                            case .left:
                                self.dimension.width = max(100, lastSize.width - worth.translation.width)
                                self.place.width = lastPosition.width + worth.translation.width
                            case .proper:
                                self.dimension.width = max(100, lastSize.width + worth.translation.width)
                            case .high:
                                self.dimension.top = max(100, lastSize.top - worth.translation.top)
                                self.place.top = lastPosition.top + worth.translation.top
                            case .backside:
                                self.dimension.top = max(100, lastSize.top + worth.translation.top)
                            }
                            self.isResizing = true
                        }
                        .onEnded { _ in
                            self.lastSize = self.dimension
                            self.lastPosition = self.place
                            self.isResizing = false
                        }
                )
        }
        .place(x: place == .left || place == .topLeft || place == .bottomLeft ? 0 : dimension.width,
                  y: place == .high || place == .topLeft || place == .topRight ? 0 : dimension.top)
    }
}

// Positionen für die Resize-Griffe
enum ResizePosition {
    case topLeft, topRight, bottomLeft, bottomRight, left, proper, high, backside
}

Leave a Reply

Your email address will not be published. Required fields are marked *