UIPinchGestureRecognizer在UIRotationGestureRecognizer之后无法正常工作

时间:2018-02-06 20:39:44

标签: ios uigesturerecognizer simultaneous

我在UIView上有2个手势识别器(旋转和捏合)。他们独立工作。如果我在捏后旋转,仍然可以正常工作。但如果我在旋转后捏住,则捏不起作用。

  • 捏:工作。
  • rotate:working。
  • (旋转 - >捏):不工作。
  • (捏 - >旋转):工作。
  • (捏 - >旋转 - >捏):不工作。

这是我的代码:

//gestures

  lazy var zoomGesture: UIPinchGestureRecognizer = {
    let zoom = UIPinchGestureRecognizer.init(target: self, action: #selector(handleZoom(_:)))
    zoom.delegate = self
    activeLayer.addGestureRecognizer(zoom)
    return zoom
  }()

  lazy var rotationGesture: UIRotationGestureRecognizer = {
    let rotation = UIRotationGestureRecognizer.init(target: self, action: #selector(handleRotation(_:)))
    rotation.delegate = self
    activeLayer.addGestureRecognizer(rotation)
    return rotation
  }()

//handlers

  @objc func handleZoom(_ gesture: UIPinchGestureRecognizer) {
    if gesture.state == .began {
      if activeLayer.initialTransform == nil {
        activeLayer.initialTransform = activeLayer.transform
      }
    } else if gesture.state == .changed {
      let scale = gesture.scale
      activeLayer.transform = activeLayer.initialTransform!.concatenating(CGAffineTransform.init(scaleX: scale, y: scale))
    } else {
      activeLayer.initialTransform = nil
    }
  }

  @objc func handleRotation(_ gesture: UIRotationGestureRecognizer) {
    if gesture.state == .began {
      if activeLayer.initialTransform == nil {
        activeLayer.initialTransform = activeLayer.transform
      }
    } else if gesture.state == .changed {
      let rotation = gesture.rotation
      activeLayer.transform = activeLayer.initialTransform!.concatenating(CGAffineTransform.init(rotationAngle: rotation))
    } else {
      activeLayer.initialTransform = nil
    }
  }

  // delegate method

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

我做错了什么或错过了什么?谢谢。

2 个答案:

答案 0 :(得分:0)

根据您的要求,这里有工作解决方案。

Swift 4

     //
     //  ViewController.swift
     //  GestureRecognizerQuestions
     //
     //  Created by Test User.
     //  Copyright © . All rights reserved.
     //

     import UIKit

     class ViewController: UIViewController , UIGestureRecognizerDelegate {

        var activeView : UIView!
        var initialTransform : CGAffineTransform?

        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
            activeView = UIView(frame: self.view.frame)
            activeView.backgroundColor = UIColor.red
            self.view.addSubview(activeView)

            let rotation = UIRotationGestureRecognizer(target: self , action: #selector(handleRotation(_:)))
            rotation.delegate = self
            activeView.addGestureRecognizer(rotation)

            let zoomGesture = UIPinchGestureRecognizer(target: self , action: #selector(handleZoom(_:)))
            zoomGesture.delegate = self
            activeView.addGestureRecognizer(zoomGesture)


        }

        //handlers

        @objc func handleZoom(_ gesture: UIPinchGestureRecognizer) {
            if gesture.state == .began {
                if self.initialTransform == nil {
                    self.initialTransform = activeView.transform
                }
            } else if gesture.state == .changed {
                let scale = gesture.scale
                activeView.transform = self.initialTransform!.concatenating(CGAffineTransform(scaleX: scale, y: scale))
            }  else if gesture.state == .ended {
                self.initialTransform = nil
            }
        }

        @objc func handleRotation(_ gesture: UIRotationGestureRecognizer) {
            if gesture.state == .began {
                if self.initialTransform == nil {
                    self.initialTransform = activeView.transform
                }
            } else if gesture.state == .changed {
                let rotation = gesture.rotation
                activeView.transform = self.initialTransform!.concatenating(CGAffineTransform(rotationAngle: rotation))
            } else if gesture.state == .ended {
                self.initialTransform = nil
            }
        }

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

答案 1 :(得分:0)

行。我了解到使用initialTransform来保持启动转换状态是一件愚蠢的事情。因为每次手势开始时,它都会改变initialTransform,这会导致一些意想不到的行为。

相反,我每次申请真正的视角后都会重置手势scalerotation

以下是代码:

  // .... gesture implementations etc ....

  @objc func handleZoom(_ gesture: UIPinchGestureRecognizer) {
    guard let activeLayer = activeLayer else {
      return
    }
    let scale = gesture.scale

    // apply scale
    activeLayer.transform = activeLayer.transform.scaledBy(x: scale, y: scale)

    // reset scale to the default value 
    gesture.scale = 1
  }

  @objc func handleRotation(_ gesture: UIRotationGestureRecognizer) {
    guard let activeLayer = activeLayer else {
      return
    }

    let rotation = gesture.rotation

    // apply rotation
    activeLayer.transform = activeLayer.transform.rotated(by: rotation)

    // reset rotation to the default value.
    gesture.rotation = 0
  }