2017-06-10 28 views
0

在iOS上的現代用戶界面中,在單個視圖上實現多個UIGestureRecognizers通常很有用,以便爲模擬真實世界的顯示對象提供更真實的行爲。在Swift 3中同時使用多個UIGestureRecognizers,如UIRotationGestureRecognizer和UIPanGestureRecognizer

例如,您可能希望既可以在屏幕上拖動視圖,也可以使用兩個手指旋轉它。

UIGestureRecognizerDelegate爲此提供了一個可選功能shouldRecognizeSimultaneouslyWith。返回true避免了僅一次一個具有手勢效果:

// MARK: - UIGestureRecognizerDelegate 
extension GestureController: UIGestureRecognizerDelegate { 

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

然而,當多個手勢識別器是活動的,特別是它UIRotationGestureRecognizer可以是令人沮喪找到工作不正常的處理程序不斷互相覆蓋的圖。

如何實現多個手勢識別器以提供平滑行爲?

回答

2

同時實現多個手勢識別器的關鍵是修改它們的CGAffineTransforms而不是覆蓋它們。

Apple > Documentation > Core Graphics > CGAffineTransform

請注意,您通常不需要創建仿射變換直接。例如,如果只想繪製縮放或旋轉的對象,則不需要構建仿射變換來完成此操作。通過移動,縮放或旋轉操作繪圖的最直接方式是調用函數 translateBy(x:y :) , scaleBy(x:y :) 或 rotate(by :)分別爲 。如果您想稍後再使用它,通常應該只創建一個仿射變換。

此外,檢測到更改時,在施加在翻譯之後,它重置發件人的值,以使翻譯不每次檢測它們時的化合物是很重要的。

例如:

@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 
    } 
} 
相關問題