# SwiftUI中使用Gesture绘图小纸条

在英语小助手中，我和小朋友们想做一个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](https://developer.apple.com/documentation/swiftui/draggesture) 的实例，在它的.onChanged中不断改变着ViewModel的当前start和end的数值，在.onEnded中把最后确定的一条Line View加到lines中去。这就是它的最终效果：

![drawline.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1646509991205/AS8xKIJA6.gif)

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

%[https://github.com/HDCodePractice/CodePracticeResult/tree/gh-pages/hd/SwiftUIPlayground/DrawLine.playground]
