From 682fbbd5b4a719cd66da89b37f58d0691bd8a20c Mon Sep 17 00:00:00 2001 From: dscyrescotti Date: Sat, 18 May 2024 02:41:14 +0700 Subject: [PATCH] feat: scroll to new added pen --- Memola/Canvas/Tool/Core/Tool.swift | 4 ++ .../Features/Memo/PenTool/PenToolView.swift | 49 +++++++++++++------ 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/Memola/Canvas/Tool/Core/Tool.swift b/Memola/Canvas/Tool/Core/Tool.swift index 43c1a36..c36ffca 100644 --- a/Memola/Canvas/Tool/Core/Tool.swift +++ b/Memola/Canvas/Tool/Core/Tool.swift @@ -5,6 +5,7 @@ // Created by Dscyre Scotti on 5/4/24. // +import Combine import SwiftUI import CoreData import Foundation @@ -19,6 +20,8 @@ public class Tool: NSObject, ObservableObject { @Published var isShaking: Bool = false @Published var shakingId: UUID = UUID() + let scrollPublisher = PassthroughSubject() + init(object: ToolObject) { self.object = object } @@ -61,6 +64,7 @@ public class Tool: NSObject, ObservableObject { if let _pen = pen.object { object.pens.add(_pen) } + scrollPublisher.send(pen.id) } func removePen(_ pen: Pen) { diff --git a/Memola/Features/Memo/PenTool/PenToolView.swift b/Memola/Features/Memo/PenTool/PenToolView.swift index 2ff0627..c2c0f85 100644 --- a/Memola/Features/Memo/PenTool/PenToolView.swift +++ b/Memola/Features/Memo/PenTool/PenToolView.swift @@ -15,7 +15,7 @@ struct PenToolView: View { let factor: CGFloat = 1.22 var body: some View { - VStack(alignment: .trailing, spacing: 0) { + ScrollViewReader { proxy in ScrollView(.vertical, showsIndicators: false) { if tool.isReordering { LazyVStack(spacing: 0) { @@ -23,12 +23,14 @@ struct PenToolView: View { if pen.strokeStyle == .marker { penView(pen) .offset(y: tool.isShaking ? 1.5 : -1.5) + .id(pen.id) } else { penView(pen) + .id(pen.id) } } } - .padding(.vertical, 5) + .padding(.vertical, 10) .padding(.leading, 40) .onAppear { withAnimation(.easeInOut.repeatForever().speed(5)) { @@ -40,23 +42,22 @@ struct PenToolView: View { LazyVStack(spacing: 0) { ForEach(tool.pens) { pen in penView(pen) + .id(pen.id) } } - .padding(.vertical, 5) + .padding(.vertical, 10) .padding(.leading, 40) } } - VStack(spacing: 0) { - Divider() - if tool.isReordering { - reorderCancelButton - } else { - newPenButton + .onReceive(tool.scrollPublisher) { id in + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { + withAnimation { + proxy.scrollTo(id) + } } } - .frame(width: width * factor - 20) } - .frame(maxHeight: (height * factor + 10) * 8) + .frame(maxHeight:( (height * factor + 10) * 7) + 20) .fixedSize() .background { HStack(spacing: 0) { @@ -66,6 +67,16 @@ struct PenToolView: View { } } .clipShape(.rect(cornerRadii: .init(bottomTrailing: 20, topTrailing: 20))) + .overlay(alignment: .bottomLeading) { + Group { + if tool.isReordering { + doneButton + } else { + newPenButton + } + } + .offset(x: 60, y: 10) + } } @ViewBuilder @@ -125,25 +136,33 @@ struct PenToolView: View { let _pen = Pen(object: pen) tool.addPen(_pen) } label: { - Image(systemName: "pencil.tip.crop.circle.badge.plus") + Image(systemName: "plus.circle.fill") .font(.title2) + .padding(1) .contentShape(.circle) + .background { + Circle() + .fill(.white) + } } .foregroundStyle(.green) .hoverEffect(.lift) - .padding(10) } - var reorderCancelButton: some View { + var doneButton: some View { Button { tool.isReordering = false } label: { Image(systemName: "xmark.circle") .font(.title2) + .padding(1) .contentShape(.circle) + .background { + Circle() + .fill(.white) + } } .hoverEffect(.lift) - .padding(10) } func penPreview(_ pen: Pen) -> some View {