前言

SwiftUI 中,我们可以通过添加不同的交互来使我们的应用程序更具交互性,这些交互可以响应我们的点击,点击和滑动。

今天,我们将回顾 SwiftUI 基本手势:

  • TapGesture
  • 长按手势
  • 拖动手势
  • 放大手势
  • 旋转手势

TapGesture

轻击手势使我们能够识别 View 上的一个或多个轻击。
我们有几种方法可以添加点击手势。

第一个是直接使用 .onTapGesture 修饰符。

Circle().onTapGesture {// Respond to Tap Gesture }

SwiftUI 文档中使用的其他选项是通过创建手势并将其配置为属性,然后将其与 .gesture(_:include :) 修饰符一起使用。

注意: 为了执行某项操作或响应轻击,我们需要使用 .onEnded 操作关闭,该操作在手势结束时触发。

struct SingleTapGestureView: View {var singleTap: some Gesture {TapGesture().onEnded { _ in// Respond to Tap Gesture}}var body: some View {Circle().gesture(singleTap)}
}

实际上,我更喜欢第二种方法,因为这样我们可以创建不同的手势并通过我们的代码重复使用它们。

因此,如果我们将代码放在一起,就可以开始编写类似的东西。

struct TapGestureView: View {@State private var isAnimating = false@State private var tapped1x = 0var singleTap: some Gesture {TapGesture().onEnded { _ intapped1x += 1withAnimation(Animation.easeOut(duration: 0.5)) {self.isAnimating = true}DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {self.isAnimating = false}}}var body: some View {VStack {Text("Tapped 1X: \(tapped1x) times").font(.caption)Circle().frame(width: 80, height: 80).foregroundColor(.orange).overlay(Text("1X").fontWeight(.medium)).background(Circle().strokeBorder(Color.blue, lineWidth: 3).scaleEffect(isAnimating ? 1.5 : 1).opacity(isAnimating ? 0 : 1)).gesture(singleTap)}}
}

类似地,我们只需使用 TapGesture(count:Int) 初始化程序就可以控制要响应的数量。

在这种情况下,您需要点击3次才能触发 .onEnded 操作关闭。

struct TapGesture3xView: View {@State private var isAnimating = false@State private var tapped3x = 0var multipleTap: some Gesture {TapGesture(count: 3).onEnded { _ intapped3x += 1withAnimation(Animation.easeOut(duration: 0.5)) {self.isAnimating = true}DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {self.isAnimating = false}}}var body: some View {VStack {Text("Tapped 3X: \(tapped3x) times").font(.caption)Circle().frame(width: 80, height: 80).foregroundColor(.orange).overlay(Text("3X").fontWeight(.medium)).background(Circle().strokeBorder(Color.blue, lineWidth: 3).scaleEffect(isAnimating ? 1.5 : 1).opacity(isAnimating ? 0 : 1)).gesture(multipleTap)}}
}

长按手势

长按手势可让我们在用户长按定义的时间后以及在用户长按的时间内执行操作。

我们可以设置一个最小持续时间,以识别我们的长按手势。 可以在 LongPressGesture 初始化程序中进行设置。

LongPressGesture(minimumDuration: 2)

然后,我们可以使用 .updating 方法在长按期间执行操作,并使用 .onEnded 在识别到我们的手势时执行操作。

在此示例中,我将在长按操作期间更新 Circle() 的大小和颜色,并且当识别出手势时,我将显示“文本已完成”。

另外,我在这里使用的是 GestureState 属性包装器,该包装器在长按期间设置为 true ,在手势结束时设置为 false 。 我正在将此属性包装器用于示例动画。

struct LongPressGestureView: View {@GestureState private var isLongPressDetected = false@State private var isDone = falsevar longPress: some Gesture {LongPressGesture(minimumDuration: 2).updating($isLongPressDetected) { currentState, gestureState, transaction inDispatchQueue.main.async {isDone = false}gestureState = currentStatetransaction.animation = Animation.easeIn(duration: 2)}.onEnded { done inisDone = done}}var body: some View {VStack {Spacer()Circle().frame(width: 10, height: 10).foregroundColor(isLongPressDetected ? .orange : .primary).scaleEffect(CGSize(width: isLongPressDetected ? 10 : 1,height: isLongPressDetected ? 10 : 1))Spacer()if isLongPressDetected {Text("Updating...")}if isDone {Text("Done")}Spacer()Text("Long Press 2 sec").padding().background(isLongPressDetected ? Color.green : Color.orange).cornerRadius(16).gesture(longPress)}}
}

拖动手势

拖动手势允许我们在拖动视图时执行操作。

我们可以利用并使用 .onChanged.onEnded 关闭方法来执行某些操作。 这两种方法都为我们提供了出色的属性 DragGesture.Value,该属性存储以下拖动动作信息:

  • location
  • predictedEndLocation
  • predictedEndTranslation
  • startLocation
  • time
  • translation

我们可以使用该属性来创建可移动视图。 在当前示例中,我使用 .onChanged 方法更新 Circle() 位置坐标。

struct DragGestureView: View {@State private var location: CGPoint = CGPoint(x: 100, y: 100)var drag: some Gesture {DragGesture(minimumDistance: 1, coordinateSpace: .local).onChanged { value inlocation = value.location}}var body: some View {Circle().frame(width: 100, height: 100).foregroundColor(.orange).position(location).gesture(drag)}
}

在这里,添加了 .onEnded 方法,以在拖动结束后重置 Circle() 位置坐标。

struct DragGestureView: View {@State private var location: CGPoint = CGPoint(x: 100, y: 100)var drag: some Gesture {DragGesture(minimumDistance: 1, coordinateSpace: .local).onChanged { value inlocation = value.location}.onEnded { value inwithAnimation(.easeOut) {location = CGPoint(x: 100, y: 100)}}}var body: some View {Circle().frame(width: 100, height: 100).foregroundColor(.orange).position(location).gesture(drag)}
}

放大手势

当我们在View上应用放大动作时,放大手势允许做出一些动作。

在这里,还有 .onChanged.onEnded 闭包,我们可以使用它们来在放大动作期间或结束时进行响应。 作为属性,接收到的是 CGFloatMagnificationGesture.Value 。 我们可以以此为例来更改视图大小。

struct MagnificationGestureView: View {@State var magnifiedValue: CGFloat = 1.0var magnification: some Gesture {MagnificationGesture().onChanged { value inmagnifiedValue = value}.onEnded { value inmagnifiedValue = 1.0}}var body: some View {Circle().frame(width: 100 * magnifiedValue, height: 100 * magnifiedValue).foregroundColor(.orange).gesture(magnification).animation(.easeOut)}
}

旋转手势

旋转手势允许旋转视图,并在旋转过程中和旋转结束时以某些动作做出响应。

它还为我们提供了 .onChanged.onEnded 闭包,这些闭包为我们提供了 RotationGesture.Value,它表示手势 Angle 值。 我们可以使用该值旋转视图。

struct RotationGestureView: View {@State private var angle = Angle(degrees: 0.0)@State private var backgroundAngle = Angle(degrees: 0.0)var rotation: some Gesture {RotationGesture().onChanged { angle inself.angle = angle}.onEnded { angle inwithAnimation(Animation.spring()) {self.backgroundAngle = angle}}}var body: some View {Rectangle().frame(width: 150, height: 150, alignment: .center).foregroundColor(.orange).rotationEffect(self.angle).gesture(rotation).background(Rectangle().shadow(color: .primary, radius: 10, x: 0.0, y: 0.01).foregroundColor(.secondary).rotationEffect(backgroundAngle))}
}

总结

上面是对 SwiftUI 基本手势的总结。我们可以实现更多的交互使我们的 App 变得更生动。

对于高级的使用,可以将手势组合或者同时使用以做出响应,或者可以实现自己的自定义手势。

关注我们

我们的愿景是希望更多的人学习和使用Swift,我们会分享以 Swift 实战、SwiftUI、Swift 基础为核心的技术干货

本文已在公众号「Swift 社区」发布,如需转载请加微信:fzhanfei,备注转载开白

探索 SwiftUI 基本手势相关推荐

  1. 历时五天用 SwiftUI 做了一款 APP,阿里工程师如何做的?

    作者|姜沂(倾寒)  出品|阿里巴巴新零售淘系技术部 导读:自 2014 年苹果发布会发布 Swift 之后, Swift 经过多年迭代,终于达到了 ABI 稳定版本,也意味着 Swift 做为稳定的 ...

  2. SwiftUI 小专栏20200817汇总

    SwiftUI 布局篇汇总 9 分钟前共695字 SwiftUI 如何编程打开Office Word PPT Excel PDF PNG iWor... 14 小时前共4389字 SwiftUI 小技 ...

  3. 免费学习 SwiftUI

    原文:Learn SwiftUI with free tutorials 作者:Paul Hudson SwiftUI 是在 WWDC19 的主题演讲期间宣布的,我们已经看过大量的免费教程,如文章,Y ...

  4. 百度发布小度在家智能屏X8,一场智能音箱边界的探索

    湖南卫视的亲子节目<少年说>中曾有过这样一幕:一位十几岁的少年站在台上向自己的父母坦白,憋了很久的一句话竟然是"我再也不想吃苹果和鸡蛋了!" 作为国内收视率居高不下的电 ...

  5. imessage_重新设计iMessage以获得更好的用户体验— UX案例研究

    imessage 体验设计 (EXPERIENCE DESIGN) Communication is a vital part of our everyday lives. We almost don ...

  6. 旋转编码器旋钮程序_让我们使用SwiftUI构建具有旋转手势的复古音频旋钮

    旋转编码器旋钮程序 SwiftUI简直就是小菜一碟 (It's A Piece Of Cake With SwiftUI) Building something as seemingly simple ...

  7. SwiftUI 手势操作

    基本概念 在ios中我们经常用到的手势操作有点击,长按,拖拽,缩放,旋转.在手势操作时,不同的手势有不同的触发函数,比如,点击在点击完成时触发某个函数,拖拽手势不仅仅在拖拽完成时触发函数,而在拖拽的过 ...

  8. 【SwiftUI模块】0004、SwiftUI-<探探App>喜欢手势卡片

    SwiftUI小功能模块系列 0001.SwiftUI自定义Tabbar动画效果 0002.SwiftUI自定义3D动画导航抽屉效果 0003.SwiftUI搭建瀑布流-交错网格-效果 0004.Sw ...

  9. android 黑屏手势动画,Android MIUI 即刻APP 返回手势及动画 探索

    swipe_left.jpeg swipe_right.jpeg 18 年底做 Readhub APP 时就加入了这个返回动画效果.一直到现在,才有时间来简单总结和封装一下. swipeback.gi ...

最新文章

  1. 全面分析Web应用程序安全漏洞——《黑客攻防技术宝典:web实战篇》
  2. 一个好用的开源在线时序图/波形图(Timing Diagram)绘制网站
  3. building commercial website using Microsoft tech stack
  4. 漫画科普:天线的原理?
  5. 如何快速弄懂一个新模型_如何评估创业项目是否靠谱?一个新的模型 | 创创锦囊...
  6. photoshop案例_玩手机不如学PS!200集入门到精通Photoshop自学教程分享3
  7. maven无法找到依赖(手动使用maven导入依赖包解决)
  8. 3.3 神策数据分析平台
  9. IE浏览器兼容性问题!(按alt+x+b不弹出兼容性窗口)
  10. ECshop商城开发系列视频教程后盾网VIP课程
  11. lol封号维护服务器,LOL玩家被封三年执着理论,腾讯客服是这样回复的
  12. Linux环境Java给图片加水印中文乱码处理
  13. python 程序运行时间长,python查看程序运行时间的方法
  14. echarts 横向条形图 对比
  15. 在 HTML 中使用 ARIA 的规则
  16. v4l2架构专题模块handler分析 -- handler使能(1)cluster
  17. Matplotlib中的“plt”和“ax”到底是什么?
  18. html如何与css样式表链接起来
  19. Wrashall算法,自反性,对称性的实现
  20. 2022最新话费充值系统源码+安装教程

热门文章

  1. c++ windows 蓝牙库_c++中蓝牙编程的库类
  2. 番茄的随笔2-准PR控制传递函数离散化
  3. 漫话:什么是平衡(AVL)树?这应该是把AVL树讲的最好的文章了
  4. linux-rm -f如何恢复
  5. OpenCV中图像的存储格式(Python版本)
  6. Hive 与 Hbase表映射(内部表与外部表),Hbase常用命令
  7. Linux组播编程 组播发送和组播接收
  8. [项目管理]敏捷宣言
  9. win10右击无法新建文件,只能新建文件夹和快捷方式
  10. 基于安卓手机使用Termux搭建web服务器教程