手势识别器无响应
Posted
技术标签:
【中文标题】手势识别器无响应【英文标题】:Gesture recognizer not responding 【发布时间】:2017-02-06 21:26:44 【问题描述】:我的视图控制器上有一个按钮,它带来了一个菜单和一个稍微透明的视图 blackView
在它后面 - 菜单类包括一个点击手势识别器,用于在点击 blackView
时关闭菜单。但是它没有响应,我不确定我的问题出在哪里。这是菜单的代码:
class MenuController: NSObject, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout
let blackView = UIView()
let collectionView: UICollectionView =
let layout = UICollectionViewFlowLayout()
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.backgroundColor = UIColor.white
return cv
()
let cellId = "cellId"
func presentMenu()
if let window = UIApplication.shared.keyWindow
blackView.backgroundColor = UIColor(white: 0, alpha: 0.5)
blackView.isUserInteractionEnabled = true
// Tap outside to dismiss
blackView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleDismiss)))
window.addSubview(blackView)
window.addSubview(collectionView)
let height: CGFloat = 200
let y = window.frame.height - height
collectionView.frame = CGRect(x: 0, y: window.frame.height, width: window.frame.width, height: height)
blackView.frame = window.frame
blackView.alpha = 0
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations:
self.blackView.alpha = 1
self.collectionView.frame = CGRect(x: 0, y: y, width: self.collectionView.frame.width, height: self.collectionView.frame.height)
, completion: nil)
func handleDismiss()
print("working")
UIView.animate(withDuration: 0.5)
self.blackView.alpha = 0
if let window = UIApplication.shared.keyWindow
self.collectionView.frame = CGRect(x: 0, y: window.frame.height, width: self.collectionView.frame.width, height: self.collectionView.frame.height)
// Collection view data sources
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return 3
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath)
return cell
override init()
super.init()
collectionView.dataSource = self
collectionView.delegate = self
collectionView.register(MenuCell.self, forCellWithReuseIdentifier: cellId)
presentMenu
被调用,当我点击视图控制器上的必要按钮时菜单出现。但是handleDismiss
没有被调用。感谢您的帮助,希望这只是一个初学者的错误!
解决方案后编辑:我在视图控制器中初始化 menuController()
,如下所示:
func showMenu()
let menuController = MenuController()
menuController.presentMenu()
并将其更改为@ronatory 的解决方案
lazy var menuController: MenuController =
let menuController = MenuController()
return menuController
()
func showMenu()
menuController.presentMenu()
解决了。
【问题讨论】:
有什么原因需要每次使用菜单的框架都要换吗? 我只是认为从逻辑上讲,早点初始化菜单是有意义的,只需将animate
代码保留在 present()
和 dismiss()
函数中
你能告诉剩下的课程吗?尤其是您如何创建collectionView
?
而且,如果我正确理解您的逻辑,您是在分别呈现菜单和视图以实现菜单视图外观吗?这不是解决这个问题的好方法。将集合视图添加到您正在呈现的视图中会更有意义。
你能在 GitHub 上分享你的项目吗?如果您需要,这将使您更容易为您提供帮助
【参考方案1】:
所以我发现的唯一方法是更改 menuController
的初始化。而不是在showMenu()
方法中初始化它(问题是你在方法中初始化它并且在方法执行之后menuController是nil):
func showMenu()
let menuController = MenuController()
menuController.presentMenu()
使用惰性存储属性替换它(在方法执行后也可以访问实例),也不需要设置blackView.isUserInteractionEnabled = true
。你可以删除它:
lazy var menuController: MenuController =
let menuController = MenuController()
return menuController
()
func showMenu()
menuController.presentMenu()
就是这样。在此更改后,您的点击手势识别器应该可以工作。我用你的项目测试了它。如果您将项目的这一部分作为代码添加到问题中会很好,这样其他人就可以更好地理解问题而无需下载项目
【讨论】:
成功了,谢谢!你知道为什么当menuController
在showMenu()
函数中初始化时手势识别器不工作吗?
我不是 100% 确定,但在我看来,我使用惰性存储属性的解决方案和 Ryan Cocuzzo 的解决方案将 menuController 实例化为类属性的原因是,如果您在首先在方法中,初始化并没有真正完成,这可能会导致您无法真正使用 MenuController 的问题,您还会看到初始实现时没有看到 3 个单元格。无论如何,我目前更喜欢惰性存储属性方式,以便在您真正需要时首先初始化 menuController
【参考方案2】:
所以,我花了一点时间,但现在这是完整的课程(工作和所有):) 快乐编码!
import UIKit
class ViewController: UIViewController
let menuController = MenuController()
// ****************** // ****************** // ****************** // ****************** // ******************
func showMenu()
menuController.presentMenu()
let tap = UITapGestureRecognizer(target: self, action: #selector(MenuController.handleDismiss))
MenuController.blackView.addGestureRecognizer(tap)
self.view.addSubview(MenuController.blackView)
// ****************** // ****************** // ****************** // ****************** // ******************
func handleDismiss()
menuController.handleDismiss()
if MenuController.blackView.alpha != 0
class MenuController: NSObject, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout
static let blackView = UIView()
func presentMenu()
if let window = UIApplication.shared.keyWindow
MenuController.blackView.backgroundColor = UIColor(white: 0, alpha: .5)
MenuController.blackView.isUserInteractionEnabled = true
// Tap outside to dismiss
window.addSubview(MenuController.blackView)
let height: CGFloat = 200
let y = window.frame.height - height
collectionView.frame = CGRect(x: 0, y: window.frame.height, width: window.frame.width, height: height)
MenuController.blackView.frame = window.frame
MenuController.blackView.alpha = 0
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations:
MenuController.blackView.alpha = 1
self.collectionView.frame = CGRect(x: 0, y: y, width: self.collectionView.frame.width, height: self.collectionView.frame.height)
, completion: nil)
func handleDismiss()
print("working")
UIView.animate(withDuration: 0.5)
MenuController.blackView.alpha = 0
if let window = UIApplication.shared.keyWindow
self.collectionView.frame = CGRect(x: 0, y: window.frame.height, width: self.collectionView.frame.width, height: self.collectionView.frame.height)
【讨论】:
我知道你找到了答案,但我非常感谢你的支持,因为这花了我一些时间来解决 谢谢!我肯定会投反对票,但请保留您所做的相关更改,而不是整个班级。请删除顶部带有我的姓名和项目名称的信息。 是啊,我没明白,哈哈 好的 @KingTim 我删除了所有不太重要的内容 一点问题都没有!以上是关于手势识别器无响应的主要内容,如果未能解决你的问题,请参考以下文章