大师学SwiftUI第12章 - 手势 Part 1

手势识别器

手势是用户在屏幕上执行的动作,如点击、滑动或捏合。这些手势很难识别,因为屏幕上只能返回手指的位置。为此,Apple提供了手势识别器。手势识别器完成所有识别手势所需的计算。所以我们不用处理众多的事件和值,只需在等待系统监测到复杂手势时发送通知并进行相应处理即可。

手势修饰符

手机设备上最常用的手势是点击,在用户手指触碰屏幕时得到识别。因这种手势使用频繁,SwiftUI定义了两个非常方便的修饰符来完成处理。

  • onTapGesture(count: Int, perform: Closure):此修饰符识别一次或多次点击。​​count​​​参数指定要多少次点击才能做手势识别(默认值为1),​​perform​​​参数是在监测到手势时执行的闭包。闭包接收一个表示视图坐标中点击位置的​​CGPoint​​值。
  • onLongPressGesture(minimumDuration: Double, maximumDistance: CGFloat, perform: Closure, onPressingChanged: Closure):此修饰符识别长按姿势(用户用手指在屏幕上长按)。​​minimumDuration​​​参数是用户长按屏幕直到识别手势的秒数。​​maximumDistance​​​参数表示手指移动距原始位置不再识别手势的点数距离。​​perform​​​参数是在确认手势时执行的闭包。最后,​​onPressingChanged​​参数是用户和结束按压视图时执行的闭包。闭包接收一个表示用户是否在按压的布尔值。

我们经常使用​​onTapGesture()​​修饰符来监测点击并执行操作(参见示例7-36)。在之前的示例中我们没有使用点击时手指的位置。这通过闭包所接收的​​CGPoint​​值实现,其中包含视图中手指的x和y坐标。在下例中,我们在点击图片时打开弹窗并展示如何访问其值。

示例12-1:监测图片上的点击手势

struct ContentView: View {
    @State private var expand: Bool = false
    
    var body: some View {
        Image(.spot1)
            .resizable()
            .scaledToFit()
            .frame(width: 160, height: 200)
            .onTapGesture { location in
                expand = true
                print("Location: \(location)")
            }
            .sheet(isPresented: $expand) {
                ShowImage()
            }
    }
}

示例12-1的代码中,定义了160乘200点的​​Image​​​视图。将​​onTapGesture()​​​和​​sheet()​​​修饰符应用于视图来监测点击并展示弹窗。以下是由弹窗所打开的​​ShowImage​​视图。

示例12-2:展开图片

import SwiftUI

struct ShowImage: View {
    var body: some View {
        Image(.spot1)
            .resizable()
            .scaledToFill()
            .edgesIgnoringSafeArea(.all)
    }
}

此视图创建一个​​Image​​视图并展开图片填满弹窗,包含安全区。结果是界面在屏幕上展示一张小图,用户点击后,会以全尺寸在弹窗中显示图片。

图12-2:响应点击手势的图片

图12-2:响应点击手势的图片

✍️跟我一起做:创建一个多平台项目。下载spot1.jpg,添加到资源目录中。使用示例12-1中的代码更新​​ContentView​​视图。创建一个SwiftUI文件ShowImage.swift,使用示例12-2中的代码更新视图。此时会在界面看到图12-1(左)中所示的界面。点击图片打开弹窗,在控制台中会打印出点击的位置。

长按手势类似于点击手势,但系统会等待一段时间来确定该手势、执行任务。通过​​onLongPressGesture()​​修饰符,我们可以设置等待时长、执行用户点击时的任务以及等手势完成,如下例所示。

示例12-3:监测长按手势

struct ContentView: View {
    @State private var expand: Bool = false
    @State private var pressing: Bool = false
    
    var body: some View {
        Image(.spot1)
            .resizable()
            .scaledToFit()
            .frame(width: 160, height: 200)
           
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值