我在UIView上有2个手势识别器(旋转和捏合)。他们独立工作。如果我在捏后旋转,仍然可以正常工作。但如果我在旋转后捏住,则捏不起作用。
这是我的代码:
//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
}
我做错了什么或错过了什么?谢谢。
答案 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,这会导致一些意想不到的行为。
相反,我每次申请真正的视角后都会重置手势scale
和rotation
。
以下是代码:
// .... 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
}