思维导图

作者:Aaron Dean

1. 基础手势

1.1 轻触手势 onTapGesture

// 1.单击(默认)
Text("单击")
    .onTapGesture(){
    print("你刚刚单击了")
}

//  2.双击
Text("双击")
    .onTapGesture(count: 2){
       print("你刚刚双击了")
}

1.2 长按手势 onLongPressGesture

// 1. 长按手势(默认0.5 秒触发)
Text("长按手势(默认)")
    .onLongPressGesture {
     print("你长按了")
  }

// 2. 长按手势(自定义)
Text("长按手势(自定义)")
     .onLongPressGesture(
           minimumDuration: 4,
           pressing: {isPressing in
            //正在按 true,中途松开或结束--false
              print(isPressing)
       }){
        print("至少长按 4 秒才能看到这句话.")
     }
    

1.3 捏合手势 MagnificationGesture

//   捏合手势:缩放效果
Text("捏合手势")
  .gesture(
         MagnificationGesture()
                .onChanged{ amount in
                    self.currentAmount = amount
                }
                .onEnded{ amount in
                    self.currentAmount = 1
                }
   )

1.4 旋转手势 RotationGesture

//   旋转手势
Text("旋转手势")
    .gesture(
         RotationGesture()
            .onChanged{ angle in
                self.currentAngle = angle
             }
            .onEnded{angle in
                self.currentAngle = .degrees(0)
            }
    )

2. 组合手势 (长按 + 拖拽)

//   长按加拖拽: 使用 sequenced(before:)方法合并两个手势
//  DragGesture 和 offset一起使用
import SwiftUI
struct GesturesBasic: View {

    @State private var currentAmount: CGFloat = 1
    @State private var currentAngle: Angle = .degrees(0)
    @State private var offset: CGSize = .zero
    @State private var longpressed = false

    var body: some View {
    
    let dragGesture = DragGesture()
            .onChanged{ value in
                self.offset = value.translation
        }
        .onEnded{ _ in
            withAnimation{
                self.offset = .zero
                self.longpressed = false
            }
        }
        
    let longPressGesture = LongPressGesture()
            .onEnded{ _ in
                withAnimation{
                    self.longpressed = true
                }
        }

    Circle()
     .fill(Color.green)
     .frame(width:60, height: 60)
     .scaleEffect(longpressed ? 1.5 : 1)
     .offset(offset)
     .gesture(longPressGesture.sequenced(before: dragGesture))
    }
}

3. 手势优先级

// 1. 父视图和子视图都有手势时,默认触发子视图的手势操作.
Text("子视图")
   .onTapGesture {
        print("子视图优先(默认")
    }

// 2.更改默认的优先顺序:highPriorityGesture
VStack{
     Text("子视图")
        .onTapGesture {
            print("子视图优先(默认)")
         }
}
.highPriorityGesture(//更改默认的优先顺序
      TapGesture()
        .onEnded{ _ in
          print("父视图优先")
        }
)

//  3.  同时触发父子视图:simultaneousGesture
VStack{
     Text("子视图")
        .onTapGesture {
            print("子视图优先(默认)")
         }
}
.simultaneousGesture(//同时触发
      TapGesture()
        .onEnded{ _ in
            print("同时触发父视图和子视图")
        }
)

4. 禁用手势 allowHitTesting

//   禁用手势:SwiftUI 所有的控件默认允许使用手势,即allowsHitTesting默认为 true,改成 false 即可禁用手势。
Text("禁用手势")
    .onTapGesture {
          print("手势被禁用了,因此你看不到这句话在控制台输出。")
     }
    .allowsHitTesting(false)

5. contentShape

// 图片或图形透明部分或背景不能被点击的处理:.contentShape(Rectangle()).
Circle()
     .fill(Color.primary)
     .frame(width: 300, height: 300)
     .contentShape(Rectangle())
     //表明圆形之外的部分也当做圆形触发,与默认相反
     .onTapGesture {
           print("圆形之外的部分也被当做圆形触发了。")
     }


//  大段空白的处理
VStack{
     Text("Spacer")
     Spacer().frame(height: 100)
     Text("大块空白")
     }
      .padding()
      .contentShape(Rectangle())
      .onTapGesture {
                print("VStack 被点击了")
}