本文原创作者:Alexander Ershov

为了实现交互手势,SwiftUI拥有手势协议(Gesture protocol)。确切来说,它实现了5种手势协议。让我们一一探索它们!

让我们从简单的 tap 手势开始。它能够通过 TapGesture 实现。让我们来创建一个能通过点击手势改变自身颜色的简单圆角矩形,你通过下图可以看到此例子的效果。😉

嗯,是时候让我们深入了解代码的实现了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
struct TapGestureExample: View {
@State var rectangleColor = Color(.green)

var body: some View {
// TapGesture creation
let tapGesture = TapGesture()
// Change color when tap ended
.onEnded { _ in
if self.rectangleColor == .red {
self.rectangleColor = .green
} else {
self.rectangleColor = .red
}
}
return Rectangle()
// Change color
.foregroundColor(rectangleColor)
.cornerRadius(40)
.frame(width: 200, height: 100, alignment: .center)
// Add the tapGesture to this view
.gesture(tapGesture)
}
}

完成简单点击事件之后,我们将要实现一个长按手势(long tap)。为了实现它我们将会使用 LongPressGesture。现在我们将会通过长按至少 2秒 以上来改变圆角矩形的颜色。让我们看看它是怎么实现的👇。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
struct LongPressGestureExample: View {
@State var rectangleColor = Color(.green)

var body: some View {
// LongPressGesture creation
// Gesture will be handled only if if takes at least 2 seconds
let longPressGesture = LongPressGesture(minimumDuration: 2, maximumDistance: 10)
.onEnded { _ in
if self.rectangleColor == .red {
self.rectangleColor = .green
} else {
self.rectangleColor = .red
}
}

return Rectangle()
// Change color
.foregroundColor(rectangleColor)
.cornerRadius(40)
.frame(width: 200, height: 100, alignment: .center)
// Add the longPressGesture to this view
.gesture(longPressGesture)
}
}

上面我们已经完成了长按手势,我们可以试着来拖动我们的矩形。拖拽手势(DragGesture)将会帮我们实现这样的效果!你可以在下面看到它实现的效果以及怎么使用代码来实现它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
struct DragGestureExample: View {
@State var rectangleOffset: CGSize = .zero

var body: some View {
// DragGesture creation
let dragGesture = DragGesture()
// When drag location is changed we recalculate offset for the rectangle
.onChanged { value in
self.rectangleOffset = value.translation
}
// When gesture ended we return the rectangle to the initial position
.onEnded { _ in
self.rectangleOffset = .zero
}

return Rectangle()
.foregroundColor(.green)
.cornerRadius(40)
// Change position for the rectangle
.offset(rectangleOffset)
.frame(width: 200, height: 100, alignment: .center)
// Add the dragGesture to this view
.gesture(dragGesture)
}
}

目前为止,我们仅仅学习了单点操作的手势,是时候来学习多点触碰的手势了。第一个是缩放手势,你在下面可以看到它具体实现的效果,为了实现这种效果,我们将会使用 MagnificationGesture。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct MagnificationGestureExample: View {
@State var rectangleScaleEffect: CGFloat = CGFloat(1)

var body: some View {
// MagnificationGesture creation
let magnificationGesture = MagnificationGesture()
// Scale effect recalculation for the rectangle
.onChanged { value in
self.rectangleScaleEffect = value
}

return Rectangle()
.foregroundColor(.green)
.cornerRadius(40)
// Change scale effect
.scaleEffect(rectangleScaleEffect)
.frame(width: 200, height: 100, alignment: .center)
// Add the magnificationGesture to this view
.gesture(magnificationGesture)
}
}

接下来最后一个就是旋转手势了,它使用 RotationGesture 来实现,现在让矩形旋转起来 🙃。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct RotationGestureExample: View {
@State var rectangleRotationAngle: Angle = .zero

var body: some View {
// DragGesture creation
let rotationGesture = RotationGesture()
// Rotation angle recalculation for the rectangle
.onChanged { value in
self.rectangleRotationAngle = value
}

return Rectangle()
.foregroundColor(.green)
.cornerRadius(40)
// Rotate the rectangle
.rotationEffect(rectangleRotationAngle)
.frame(width: 200, height: 100, alignment: .center)
// Add the rotationGesture to this view
.gesture(rotationGesture)
}
}

就这么多啦 😊,我们学习了所有SwiftUI默认的手势,如果你想更深入地探索它们,可以去阅读 官方文档