Ios 同时使用多个UIGestureRecognitor,如UIRotationGestureRecognitor&;Swift 3中的UIPAngestureRecognitor

Ios 同时使用多个UIGestureRecognitor,如UIRotationGestureRecognitor&;Swift 3中的UIPAngestureRecognitor,ios,swift,uigesturerecognizer,uipangesturerecognizer,Ios,Swift,Uigesturerecognizer,Uipangesturerecognizer,在iOS上的现代用户界面中,在一个视图上实现多个UIgestureRecognitor通常很有用,以便为模拟真实世界的显示对象提供更真实的行为 例如,您可能希望既能在屏幕上拖动视图,又能使用两根手指旋转视图 为此,UIgestureRecognitizerDelegate提供了一个可选功能应与同时识别。返回true一次只能避免一个手势生效: // MARK: - UIGestureRecognizerDelegate extension GestureController: UIGestureR

在iOS上的现代用户界面中,在一个视图上实现多个UIgestureRecognitor通常很有用,以便为模拟真实世界的显示对象提供更真实的行为

例如,您可能希望既能在屏幕上拖动视图,又能使用两根手指旋转视图

为此,
UIgestureRecognitizerDelegate
提供了一个可选功能
应与
同时识别。返回
true
一次只能避免一个手势生效:

// MARK: - UIGestureRecognizerDelegate
extension GestureController: UIGestureRecognizerDelegate {

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
}
但是,当多个手势识别器处于活动状态时,尤其是
UIRotationGestureRecognizer
当处理程序不断相互覆盖时,发现视图的行为异常可能会令人沮丧


如何实现多个手势识别器以提供平滑的行为?

同时实现多个手势识别器的关键是修改它们的
CGAffineTransforms

:

请注意,通常不需要直接创建仿射变换。例如,如果只想绘制缩放或旋转的对象,则无需构造仿射变换即可。无论是通过移动、缩放还是旋转操作图形,最直接的方法是调用函数 translateBy(x:y:) , scaleBy(x:y:) 或 轮换(按:) 分别地如果以后要重用仿射变换,通常只应创建仿射变换

此外,当检测到更改时,在应用翻译后,重要的是重置发送方的值,以便每次检测到翻译时不会合成

例如:

@IBAction func rotateAction(_ sender: UIRotationGestureRecognizer) {
    guard let view = sender.view else { return }

    switch sender.state {
    case .changed:
        view.transform = view.transform.rotated(by: sender.rotation)
        sender.rotation = 0
    default: break
    }
}
@IBAction func panAction(_ sender: UIPanGestureRecognizer) {
    guard let view = sender.view else { return }

    switch sender.state {
    case .changed:
        let translationX = sender.translation(in: view).x
        let translationY = sender.translation(in: view).y

        view.transform = view.transform.translatedBy(x: translationX, y: translationY)
        sender.setTranslation(CGPoint.zero, in: view)
    default: break
    }
}