SwiftUI中的手势(MagnificationGesture、 RotationGesture)

news2025/1/13 13:20:58

通过前两篇文章的探索,手势的基本使用规则已经较深的了解,本篇文章主要看看放缩手势MagnificationGesture和旋转手势RotationGesture

MagnificationGesture 放缩手势

放缩手势在App中用的也比较广泛,下面先看一个示例效果:
在这里插入图片描述
上面示例中将图片进行了放大,主要使用了MagnificationGesture手势,并对该手势添加了.updating.onEnded修饰符。

在添加.updating修饰符的时候绑定了一个@GestureState修饰的scalingRatio变量,用来记录每次放大的比例值,每次放缩结束该值重置。

同时为了每次的放缩都基于上次的大小继续放缩,需要用一个@State修饰的变量记录每次放缩结束的比例值,并在.onEnded修饰符中进行赋值。

.gesture(
  MagnificationGesture()
    .updating($scalingRatio, body: { value, state, _ in
      state = value
    })
    .onEnded({ value in
      lastRatio *= value
    })
)

有了这两个值后,在Image图片上添加.scaleEffect修饰符,改变Image的尺寸。

.scaleEffect(scalingRatio)
.scaleEffect(lastRatio)

如果用一个.scaleEffect修饰符,记得将两个变量相乘。

.scaleEffect(scalingRatio * lastRatio)

另外在视图的顶部对scalingRatiolastRatio两个变量进行了显示,可以直观的观察整个放缩过程中,这两个变量的变化。

在松手的时候,想要将图片变回原来的尺寸,只需要将lastRatio以及相关代码移除即可。

完成代码如下:

struct MagnificationGestureDemo: View {

  @GestureState private var scalingRatio: CGFloat = 1.0
  @State private var lastRatio: CGFloat = 1.0

  var body: some View {
    ZStack {
      VStack {
        Text("scalingRatio: \(scalingRatio)")
        Text("lastRatio: \(lastRatio)")
        Spacer()
      }
      Image("liuyifei")
        .resizable()
        .frame(width: 200, height: 260)
        .scaleEffect(scalingRatio)
        .scaleEffect(lastRatio)
        .gesture(
          MagnificationGesture()
            .updating($scalingRatio, body: { value, state, _ in
              state = value
            })
            .onEnded({ value in
              lastRatio *= value
            })
      )
    }
  }
}

RotationGesture 旋转手势

旋转手势和放缩手势用法基本上是一致的,先看一下示例效果:
在这里插入图片描述
上面示例中将图片进行了旋转,主要使用了RotationGesture手势,并对该手势添加了.updating.onEnded修饰符。

在添加.updating修饰符的时候绑定了一个@GestureState修饰的rotateAngle变量,用来记录每次旋转的角度,每次旋转结束该值重置。

同时为了每次的旋转都基于上次的角度继续旋转,需要用一个@State修饰的变量记录每次旋转的角度,并在.onEnded修饰符中进行赋值。

.gesture(
  RotationGesture()
    .updating($rotateAngle, body: { value, state, _ in
      state = value
    })
    .onEnded({ value in
      let newDegress = lastAngle.degrees + value.degrees
      lastAngle = Angle(degrees: newDegress)
    })
)

有了这两个值后,在Image图片上添加.rotationEffect修饰符,改变Image的尺寸。

.rotationEffect(rotateAngle)
.rotationEffect(lastAngle)

如果用一个.rotationEffect修饰符,需要将两个变量的degrees相加构建一个新的Angle传入进去。

.rotationEffect(Angle(degrees: rotateAngle.degrees + lastAngle.degrees))

另外在视图的顶部对rotateAnglelastAngle两个变量进行了显示,可以直观的观察整个旋转过程中,这两个变量的变化。

在松手的时候,想要将图片变回原来的角度,只需要将lastAngle以及相关代码移除即可。

完成代码如下:

struct RotationGestureDemo: View {
  @GestureState private var rotateAngle: Angle = Angle(degrees: 0.0)
  @State private var lastAngle: Angle = Angle(degrees: 0.0)

  var body: some View {
    ZStack {
      VStack {
        Text("rotateAngle: \(rotateAngle.degrees)")
        Text("lastAngle: \(lastAngle.degrees)")
        Spacer()
      }
      Image("liuyifei")
        .resizable()
        .frame(width: 200, height: 260)
        .rotationEffect(rotateAngle)
        .rotationEffect(lastAngle)
        .gesture(
          RotationGesture()
            .updating($rotateAngle, body: { value, state, _ in
              state = value
            })
            .onEnded({ value in
              let newDegress = lastAngle.degrees + value.degrees
              lastAngle = Angle(degrees: newDegress)
            })
      )
    }
  }
}

最后,希望能够帮助到有需要的朋友,如果觉得有帮助,还望点个赞,添加个关注,笔者也会不断地努力,写出更多更好用的文章。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1691407.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mybatis Cache(二)MybatisCache+Redis

前面提到了,使用mybatis cache,一般是结合redis使用。 一、demo 1、数据表 create table demo.t_address (id int auto_incrementprimary key,address_name varchar(200) null,address_code varchar(20) null,address_type int n…

鸿蒙系统与OpenHarmony:中国科技行业的新动力与就业前景

背景 经历近年来的迅猛发展,鸿蒙原生应用数量已突破4000款,生态设备数量超过8亿台,开发者群体壮大至220万人。更为显著的是,鸿蒙系统在中国市场的份额已经超过了15%,稳居第三大操作系统,其生态之树已然枝繁…

牛客NC236 最大差值【simple 动态规划 Java/Go/PHP】

题目 题目链接: https://www.nowcoder.com/practice/a01abbdc52ba4d5f8777fb5dae91b204 思路 不难看出该题可以使用动态规划的方式解题。 在循环数组的过程中,记录截止到当前位置-1的最小值, 然后用当前的值去计算最大的差值。Java代码 im…

【软件设计师】下午题总结-数据流图、数据库、统一建模语言

下午题总结 1 试题一1.1 结构化语言 2 试题二弱实体增加权限增加实体间联系和联系的类型 3 试题三3.1 UML关系例子 3.2 例子(2016上半年)3.3 设计类分类3.3.1 接口类3.3.2 控制类3.3.3 实体类 3.4 简答题3.4.1 简要说明选择候选类的原则3.4.2 某个类必须…

【NOIP2014普及组复赛】题4:子矩阵

题3:子矩阵 【题目描述】 给出如下定义: 1.子矩阵:从一个矩阵当中选取某些行和某些列交叉位置所组成的新矩阵(保持行与列的相对顺序)被称为原矩阵的一个子矩阵。 例如,下面左图中选取第 2 、 4 2、4 2、…

结构安全预警?事前发现?人工观测VS自动化监测,谁更胜一筹?

人工检测是依靠目测检查或借助于便携式仪器测量得到的信息,但是随着整个行业的发展,传统的人工检测方法已经不能满足检测需求,从人工检测到自动化监测已是必然趋势。 a. 从检测方式看 人工检测需要耗费大量的精力,从摆放检测工具到…

web前端的路径和Servlet注解开发

目录 在web前端的两种路径 绝对路径的两种写法 相对路径 相对路径进阶 使用注解开发Servlet 使用注解开发Servlet的注意事项 使用idea创建servlet模板 在web前端的两种路径 绝对路径的两种写法 1.带网络三要素 http://ip地址:端口号/资源路径 2.不带网络三要素 /资源路…

Java开发大厂面试第17讲:MySQL 的优化方案有哪些?数据库设计、查询优化、索引优化、硬件和配置优化等

性能优化(Optimize)指的是在保证系统正确性的前提下,能够更快速响应请求的一种手段。而且有些性能问题,比如慢查询等,如果积累到一定的程度或者是遇到急速上升的并发请求之后,会导致严重的后果,…

Springboot开发 -- Postman 调试类型详解

引言 在 Spring Boot 应用开发过程中,接口测试是必不可少的一环。Postman 作为一款强大的 API 开发和测试工具,可以帮助开发者轻松构建、测试和管理 HTTP 请求。本文将为大家介绍如何在 Spring Boot 开发中使用 Postman 进行接口测试。 一、准备工作 安…

Three.js点与材质(Points)

球几何体 // 创建球几何体 const sphereGeometry new THREE.SphereGeometry(3, 20, 20) const material new THREE.MeshBasicMaterial({color: 0xff0000,wireframe: true // 以线框的形式显示顶点 }) const mesh new THREE.Mesh(sphereGeometry, material) scene.add(mesh)点…

淘宝订单系统ERP中如何接入平台订单信息?(订单API)

淘宝开放平台中有交易API,里面有各种关于交易的API接口。但是申报应用权限的审核流程严格又漫长。不少公司费时费力的申请后,结果还是没有审批下来。 调用淘宝自定义接口custom,可以实现淘宝开放平台API的调用。技术人员会根据您需要的接口做…

力扣第141题和142题-环形链表,是否有环,环的入口节点

因这2道题均不改变链表结构,所以可以不创建新的临时头结点 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ bool hasCycle(struct ListNode *head) {if(headNULL||head->nextNULL)//若只有一个数…

恶劣天候鲁棒三维目标检测论文整理

恶劣天候鲁棒三维目标检测论文整理 Sunshine to Rainstorm: Cross-Weather Knowledge Distillation for Robust 3D Object DetectionRobo3D: Towards Robust and Reliable 3D Perception against CorruptionsLossDistillNet: 3D Object Detection in Point Cloud Under Harsh W…

2024目前网上最火短剧机器人做法,自动搜索发剧 自动更新资源 自动分享资源

目前整个项目圈子很多的短剧机器人,我写的,自动搜索发剧,自动更新资源,自动分享资源,前段时间大部分做短剧的都是做的短剧分成,我的一个学员做的30W播放量才200块收益,备受启发,我就…

迷你手持小风扇到底哪个牌子最好?揭秘迷你手持手持小风扇排行榜

在炎炎夏日,迷你手持小风扇成为了我们不可或缺的清凉伴侣。然而,面对市场上琳琅满目的品牌,迷你手持小风扇到底哪个牌子最好?今天,我将揭秘迷你手持小风扇排行榜,带大家一探各大品牌的魅力,让你…

交叉编译程序,提示 incomplete type “struct sigaction“ is not allowed

问题描述 incomplete type "struct sigaction" is not allowed解决办法 在代码的最顶端添加如下代码即可 #define _XOPEN_SOURCE此定义不是简单的宏定义,是使程序符合系统环境的不可缺少的部分 _XOPEN_SOURCE为了实现XPG:The X/Open Porta…

Vitis HLS 学习笔记--抽象并行编程模型-控制驱动与数据驱动

目录 1. 简介 2. Takeaways 3. Data-driven Task-level Parallelism 3.1 simple_data_driven 示例 3.2 分析 hls::task 类 3.3 分析通道(Channel) 3.4 注意死锁 4. Control-driven Task-level Parallelism 4.1 理解控制驱动的 TLP 4.2 simple_control_driven 示例 4…

59 多次 mmap 虚拟地址的关系

前言 这是来自于网友的一篇帖子 然后 我们这里来探究一下这个问题 主要是 多次连续的 mmap 获取到的 虚拟地址区域 是否连续 以及 衍生出的一些其他的问题 从 mmap 的实现 我们可以知道, mmap 的空间是 自顶向下 分配的, 因此 两块空间应该是连续的, 第一块在上面, 第二块…

二百三十七、Hive——DWS层生成每个清洗字段的异常情况记录

一、目的 在Hive中对每种业务数据的清洗字段的异常数据进行记录 例如这张图,上面是原始数据,下面是每台雷达每天的异常字段的记录 二、实施步骤 (一)建表 create table if not exists dws_data_clean_record_queue(data_ty…

Go团队:Go是什么

2024年的Google I/O大会[1]如期而至。 这届大会的核心主旨毫无疑问是坚定不移的以AI为中心:Google先是发布了上下文长度将达到惊人的200万token的Gemini 1.5 Pro[2],然后面对OpenAI GPT-4o的挑衅,谷歌在大会上直接甩出大杀器Project Astra[3]…