UIPinchGestureRecognizer 在 UIRotationGestureRecognizer 之后不起作用
Posted
技术标签:
【中文标题】UIPinchGestureRecognizer 在 UIRotationGestureRecognizer 之后不起作用【英文标题】:UIPinchGestureRecognizer is not working after UIRotationGestureRecognizer 【发布时间】:2018-02-06 20:39:44 【问题描述】:我在 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
我做错了什么或错过了什么?谢谢。
【问题讨论】:
查看this question,似乎是一个类似的问题。 运气不好我已经查过了。 你是如何利用这个 activeLayer 的? @iosTeam,没什么大不了的。它是一个 UIView 子类,只有一个名为initialTransform
的变量来保存手势开始时的变换信息。
【参考方案1】:
根据您的要求,这里有可行的解决方案。
斯威夫特 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
【讨论】:
嘿@Arda Oğul Üçpınar 你觉得我的解决方案对你有帮助吗?【参考方案2】:好的。我了解到使用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
【讨论】:
以上是关于UIPinchGestureRecognizer 在 UIRotationGestureRecognizer 之后不起作用的主要内容,如果未能解决你的问题,请参考以下文章
UIPinchGestureRecognizer 与 UILongTapGestureRecognizer 的使用没有问题
使用 UIPinchGestureRecognizer 调整 UIView 的大小
UIPinchGestureRecognizer。放大手指的位置,而不仅仅是中心[重复]
UIPinchGestureRecognizer 向内捏“慢”