同时使用多个 UIGestureRecognizers,如 UIRotationGestureRecognizer &Swift 3 中的 UIPanGestureRecognizer [英] Using multiple UIGestureRecognizers simultaneously like UIRotationGestureRecognizer & UIPanGestureRecognizer in Swift 3

查看:18
本文介绍了同时使用多个 UIGestureRecognizers,如 UIRotationGestureRecognizer &Swift 3 中的 UIPanGestureRecognizer的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In modern user interfaces on iOS, it is often useful to implement multiple UIGestureRecognizers on a single view, in order to provide more realistic behavior of displayed objects that model the real world.

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

For example, you might want to be able to both drag a view around the screen, but also use two fingers to rotate it.

UIGestureRecognizerDelegate 为此提供了一个可选函数 shouldRecognizeSimultaneouslyWith.返回 true 避免一次只有一个手势有效:

The UIGestureRecognizerDelegate provides an optional function shouldRecognizeSimultaneouslyWith for this purpose. Returning true avoids only one gesture having effect at a time:

// MARK: - UIGestureRecognizerDelegate
extension GestureController: UIGestureRecognizerDelegate {

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
}

但是,当多个手势识别器处于活动状态时,尤其是 UIRotationGestureRecognizer,当处理程序不断相互覆盖时,发现视图行为异常可能会令人沮丧.

However, when multiple gesture recognisers are active, especially UIRotationGestureRecognizer it can be frustrating to find the view behaving unexpectedly as the handlers constantly override each other.

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

How can multiple gesture recognisers be implemented to provide smooth behavior?

推荐答案

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

The key to implementing multiple gesture recognisers simultaneously is modifying their CGAffineTransforms rather than overwriting them.

Apple > 文档 > 核心图形 > CGAffineTransform:

请注意,您通常不需要直接创建仿射变换.例如,如果您只想绘制缩放或旋转的对象,则没有必要构建仿射变换来执行此操作.操作绘图的最直接方法(无论是通过移动、缩放还是旋转)是调用函数translateBy(x:y:),scaleBy(x:y:), 或者旋转(由:), 分别.如果您想稍后重用它,您通常应该只创建一个仿射变换.

Note that you do not typically need to create affine transforms directly. If you want only to draw an object that is scaled or rotated, for example, it is not necessary to construct an affine transform to do so. The most direct way to manipulate your drawing—whether by movement, scaling, or rotation—is to call the functions translateBy(x:y:) , scaleBy(x:y:) , or rotate(by:) , respectively. You should generally only create an affine transform if you want to reuse it later.

此外,当检测到更改时,在应用翻译后,重置发送者的值很重要,这样每次检测到翻译时都不会复合.

Furthermore, when changes are detected, after applying the translation, it is important to reset the value of the sender, so that the translations do not compound each time they are detected.

例如:

@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
    }
}

这篇关于同时使用多个 UIGestureRecognizers,如 UIRotationGestureRecognizer &Swift 3 中的 UIPanGestureRecognizer的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆