#1 onLongPressGesture

功能

为任意 View 添加长按手势识别。当用户持续按压且达到指定时长、同时手指偏移不超过阈值时,视为一次有效长按;可实时获取按压状态以驱动过渡动画。

参数说明

  • minimumDuration:触发所需最短按压时间(秒)。
  • maximumDistance:手指允许的最大偏移,单位为点;超限即判定为取消。
  • onPressingChanged:按压状态变化回调;true 表示按下,false 表示抬起或滑出。
  • action:满足时长与偏移条件后执行的一次性回调。

代码示例

swift 复制代码
struct LongPressGestureBootcamp: View {
    
    @State var isComplete: Bool = false
    @State var isSuccess: Bool = false
    var body: some View {
        
        VStack {
            Rectangle()
                .fill(isSuccess ? .green : .blue)
                .frame(maxWidth: isComplete ? .infinity : 0)
                .frame(height: 56)
                .frame(maxWidth: .infinity, alignment: .leading)
                .background(.gray)
            
            HStack {
                Text("CLICK HERE")
                    .foregroundStyle(.white)
                    .padding()
                    .background(.black)
                    .cornerRadius(8)
                    .onLongPressGesture(
                        minimumDuration: 1.0,
                        maximumDistance: 56) { (isPressing) in
                            // start of press -> min duration
                            if isPressing {
                                withAnimation(.easeInOut(duration: 1.0)) {
                                    isComplete = true
                                }
                            }
                            else {
                                DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                                    if !isSuccess {
                                        withAnimation(.easeInOut) {
                                            isComplete = false
                                        }
                                    }
                                }
                            }
                        } perform: {
                            // at the min duration
                            withAnimation(.easeInOut) {
                                isSuccess = true
                            }
                        }
                
                Text("RESET")
                    .foregroundStyle(.white)
                    .padding()
                    .background(.black)
                    .cornerRadius(8)
                    .onTapGesture {
                        isComplete = false;
                        isSuccess = false;
                    }
            }
        }
        
        
//        Text(isComplete ? "COMPLETED" : "NOT COMPLETE")
//            .padding()
//            .background(isComplete ? .green : .gray)
//            .cornerRadius(8)
////            .onTapGesture {
////                withAnimation {
////                    isComplete.toggle()
////                }
////            }
//            .onLongPressGesture(minimumDuration: 1.0, maximumDistance: 50, perform: {
//                isComplete.toggle()
//            })
    }
}

注意事项

  1. 若同时附加 .onTapGesture,长按结束后可能额外触发一次点按,应通过状态标志互斥。
  2. onPressingChanged 中更新界面时,请使用 withAnimation 保证过渡流畅。
  3. 耗时操作请置于 action 的异步闭包内,避免阻塞主线程。
相关推荐
天桥吴彦祖2 天前
判断iOS如何监听手机屏幕是否锁屏
ios
东坡肘子2 天前
SPI 加入 Apple,Swift 迈向自举 -- 肘子的 Swift 周报 #142
人工智能·swiftui·swift
敲代码的鱼2 天前
PDF 预览与签名批注写回 支持安卓 iOS 鸿蒙 UTS插件
android·前端·ios
时光足迹3 天前
uni-app 视频通话实战:康复师与患者视频问诊的 6 个致命 Bug 与解决方案
android·ios·uni-app
时光足迹3 天前
JPush UniApp UTS 插件完全参考手册:API、事件与厂商通道一网打尽
vue.js·ios·uni-app
时光足迹3 天前
极光推送全攻略(下):uni-app 代码实现与 iOS 排查实战
vue.js·ios·uni-app
时光足迹3 天前
极光推送全攻略(上):被iOS证书折磨了三天,我写了一份前端也能看懂的避坑指南
前端·ios·uni-app
编程范式4 天前
SwiftUI 中图片如何适配可用空间
ios
songgeb6 天前
启发式 UI 自动化:从线性剧本到每步读屏决策
ios·测试
神奇的程序员7 天前
开发了一个进阶版Apple健康
swiftui·apple·apple watch