SwiftUI中使用Gesture绘图小纸条

SwiftUI中使用Gesture绘图小纸条

使用Gesture和Path制作简易绘线

·

1 min read

在英语小助手中,我和小朋友们想做一个WordSearch的记忆单词的游戏。其中有一个用手指在屏幕上划过划出一条粗线的功能。今天在上课时我们一起练习了一下。这里记下一个小纸条,以备后查。

准备一个Line

import SwiftUI
struct Line : View {
    let id = UUID()
    let start : CGPoint
    let end : CGPoint

    var body: some View{
        Path{ path in
            path.move(to: start)
            path.addLine(to: end)
        }
        .strokedPath(StrokeStyle(lineWidth: 10, lineCap: .round))
    }
}

extension Line:Identifiable{}

这个Line View接受start和end的坐标,画出一个两头圆圆的线条。为了让它可以在View中ForEach,加入了Identifiable的Protocols支持。

准备一个ViewModel

import SwiftUI
struct ViewModel{
    var start = CGPoint(x: 0, y: 0)
    var end =  CGPoint(x: 0, y: 0)
    var lines : [Line] = []
}

这里的start和end存放着当前正在画的Line,而lines是已经画出来的Line们。

绘图View

import SwiftUI
struct DragGestureView : View {
    @State var vm : ViewModel = ViewModel()

    var body: some View{
        ZStack{
            Color.red
            Line(start: vm.start, end: vm.end)
            ForEach(vm.lines){line in
                line
            }
        }
        .gesture(drag)
    }

    var drag : some Gesture{
        DragGesture(minimumDistance: 0)
            .onChanged{value in
                vm.start = value.startLocation
                vm.end = value.location
            }
            .onEnded{value in
                vm.lines.append(
                    Line(start: value.startLocation,
                         end: value.location
                    ))
            }
    }
}

这里是gesture的使用方法。任意一个View(这里我用的是最外层的ZStack)都可以加入.gesture modifier,它接受一个Gesture的实例,这里我使用drag建立了一个DragGesture 的实例,在它的.onChanged中不断改变着ViewModel的当前start和end的数值,在.onEnded中把最后确定的一条Line View加到lines中去。这就是它的最终效果:

drawline.gif

整体看下来,Gesture的使用还是很简单方便的,这个项目可以在github找到: