前言在SwiftUI中,我们可以通过添加不同的交互来响应我们的点击、点击和滑动,从而使我们的应用程序更具交互性。今天,我们将回顾基本的SwiftUI手势:TapGesture长按手势拖动手势放大手势旋转手势TapGestureTap手势允许我们识别视图上的一次或多次点击。我们有多种方法来添加点击手势。第一种是直接使用.onTapGesture修饰符。Circle().onTapGesture{//RespondtoTapGesture}SwiftUI文档中使用的另一个选项是创建手势并将其配置为属性,然后将其与.gesture(_:include:)修饰符一起使用。注意:为了执行动作或响应点击,我们需要关闭.onEnded动作,该动作在手势结束时触发。structSingleTapGestureView:View{varsingleTap:someGesture{TapGesture().onEnded{_in//RespondtoTapGesture}}varbody:someView{Circle().gesture(singleTap)}}实际上,我更喜欢第二种方法,因为那样我们可以创建不同的手势并重复使用他们通过我们的代码。所以如果我们把代码放在一起,我们就可以开始写类似的东西了。structTapGestureView:View{@StateprivatevarisAnimating=false@Stateprivatevartapped1x=0varsingleTap:someGesture{TapGesture().onEnded{_intapped1x+=1withAnimation(Animation.easeOut(duration:0.5)){self.isAnimating=true}DispatchQueue.main.asyncAfter:.de(现在()+0.5){self.isAnimating=false}}}varbody:someView{VStack{Text("Tapped1X:\(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操作关闭。structTapGesture3xView:View{@StateprivatevarisAnimating=false@Stateprivatevartapped3x=0varmultipleTap:someGesture{TapGesture(count:3).onEnded{_intapped3x+=1withAnimation(Animation.easeOut(duration:0.5)){self.isAnimating=true}DispatchyncueAfter(deadline:.now()+0.5){self.isAnimating=false}}}varbody:someView{VStack{Text("Tapped3X:\(tapped3x)times").font(.caption)Circle().frame(宽度:80,高度: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初始化器中设置。LongPressGesture(minimumDuration:2)然后,我们可以使用.updating方法在长按期间执行操作,并使用.onEnded在我们的手势被识别时执行操作。在这个例子中,我在长按期间更新了Circle()的大小和颜色,当识别到手势时,我显示“文本已完成”。此外,我在这里使用GestureState属性包装器,它在长按期间设置为true,在手势结束时设置为false。我将此属性包装器用于示例动画。structLongPressGestureView:View{@GestureStateprivatevarisLongPressDetected=false@StateprivatevarisDone=falsevarlongPress:someGesture{LongPressGesture(minimumDuration:2).updating($isLongPressDetected){currentState,gestureState,transactioninDispatchQueue.main.async{isDone=false}gestureState=currentStatetransaction.animation=动画=easeIn(duration:2)}.onEnded{doneinisDone=done}}varbody:someView{VStack{Spacer()Circle().frame(width:10,height:10).foregroundColor(isLongPressDetected?.orange:.primary).scaleEffect(CGSize(width:isLongPressDetected?10:1,height:isLongPressDetected?10:1))Spacer()ifisLongPressDetected{Text("Updating...")}ifisDone{Text("Done")}Spacer()Text("LongPress2sec").padding().background(isLongPressDetected?Color.green:Color.orange).cornerRadius(16).gesture(longPress)}}}拖动手势拖动手势允许我们在拖动视图的同时执行操作。我们可以利用和使用.onChanged和.onEnded关闭方法来执行某些操作。这两种方法都为我们提供了出色的属性DragGesture.Value,它存储以下拖动手势信息:locationpredictedEndLocationpredictedEndTranslationstartLocationtimetranslation我们可以使用此属性创建可移动视图。在当前示例中,我使用.onChanged方法更新Circle()位置坐标。structDragGestureView:View{@Stateprivatevarlocation:CGPoint=CGPoint(x:100,y:100)vardrag:someGesture{DragGesture(最小距离:1,coordinateSpace:.local).onChanged{valueinlocation=value.location}}varbody:someView{Circle(.frame(width:100,height:100).foregroundColor(.orange).position(location).gesture(drag)}}这里添加.onEnded方法,在拖动结束后重置Circle()的位置坐标。structDragGestureView:View{@Stateprivatevarlocation:CGPoint=CGPoint(x:100,y:100)vardrag:someGesture{DragGesture(最小距离:1,coordinateSpace:.local).onChanged{valueinlocation=value.location}.onEnded{valueinwithAnimation(.easeOut)){location=CGPoint(x:100,y:100)}}}varbody:someView{Circle().frame(width:100,height:100).foregroundColor(.orange).position(location).gesture(drag))}}放大手势当我们在视图上应用放大动作时,放大手势允许进行一些动作。在这里,还有.onChanged和.onEnded闭包,我们可以使用它们在缩放操作结束期间或结束时进行响应。作为属性接收的是CGFloat的MagnificationGesture.Value。我们可以以此为例来更改视图大小。structMagnificationGestureView:View{@StatevarmagnifiedValue:CGFloat=1.0varmagnification:someGesture{MagnificationGesture().onChanged{valueinmagnifiedValue=value}.onEnded{valueinmagnifiedValue=1.0}}varbody:someueView{Circle().frame(宽度:10Value*,放大:100*magnifiedValue).foregroundColor(.orange).gesture(magnification).animation(.easeOut)}}旋转手势旋转手势允许旋转视图,并在旋转期间和结束时响应某些动作。它还为我们提供了.onChanged和.onEnded闭包,它们为我们提供了代表手势角度值的RotationGesture.Value。我们可以使用这个值来旋转视图。structRotationGestureView:View{@Stateprivatevarangle=Angle(degrees:0.0)@StateprivatevarbackgroundAngle=Angle(degrees:0.0)varrotation:someGesture{RotationGesture().onChanged{angleinself.angle=angle}.onEnded{angleinwithAnimation(Animation.spring()){self.backgroundAngle=angle}}}varbody:someView{Rectangle().frame(width:150,height:150,alignment:.center).foregroundColor(.orange).rotationEffect(self.angle).gesture(旋转).background(Rectangle().shadow(color:.primary,radius:10,x:0.0,y:0.01).foregroundColor(.secondary).rotationEffect(backgroundAngle))}}总结以上是对基本手势的总结斯威夫特用户界面。我们可以实现更多的交互,让我们的App更加生动。对于高级用法,可以组合或同时使用手势来响应,或者您可以实现自己的自定义手势。
