UITapGestureRecognizer 在属于另一个控制器的视图中不起作用

Posted

技术标签:

【中文标题】UITapGestureRecognizer 在属于另一个控制器的视图中不起作用【英文标题】:UITapGestureRecognizer does not work in view which belong to another controller 【发布时间】:2017-05-22 16:37:15 【问题描述】:
 @IBAction func popView(_ sender: UIButton) 
    let popView = PopView()
    popView.setVisible()
    popView.animateView(view: popView.contentView)


popView 是一个视图控制器,里面有一些视图,popView 在它的 init() 中使用 setup() 来设置这些视图。

    func setup()
    view.frame = UIScreen.main.bounds

    baseView.frame = view.frame
    baseView.backgroundColor = UIColor.black
    //baseView.alpha = appearence.backgroundAlpha
    view.addSubview(baseView)

    contentView.backgroundColor = UIColor.white
    contentView.layer.cornerRadius = appearence.cornerRadius
    contentView.frame = CGRect(x: 10, y: 10, width: appearence.width, height: appearence.height)
    contentView.layer.masksToBounds = true
    contentView.center = CGPoint(x: self.view.bounds.midX , y: self.view.bounds.midY )


    baseView.addSubview(contentView)

    headView.frame = CGRect(x: 0, y: 0, width: contentView.bounds.width, height: contentView.bounds.height / 2)
    headView.backgroundColor = UIColorFromRGB(0xE64D4D)
    contentView.addSubview(headView)



    headImageView.image = UIImage(named: headImage)
    headImageView.contentMode = .center
    headImageView.frame.size = headImageView.image!.size
    headImageView.center = CGPoint(x: headView.bounds.midX, y: headView.bounds.midY)
    headView.addSubview(headImageView)



    let recognizer = UITapGestureRecognizer(target: self, action: #selector(self.hide(_: )))
    recognizer.numberOfTapsRequired = 1
    contentView.addGestureRecognizer(recognizer)
    print(String(describing: contentView.gestureRecognizers))
 

contentView 有一个 Tapgesturerecognizer,但是当我点击它时它不起作用

func hide(_ recognizer: UITapGestureRecognizer)
    self.view.removeFromSuperview()

popView 由 ViewController 类中的以下代码创建

 @IBAction func popView(_ sender: UIButton) 
    let popView = PopView()
    popView.setVisible()
    popView.animateView(view: popView.contentView)



func setVisible()
    let rootView = UIApplication.shared.keyWindow! as UIWindow
    rootView.addSubview(self.view)



func animateView(view: UIView)
    view.center = CGPoint(x: self.view.bounds.midX, y: self.view.bounds.minY - view.bounds.midY)
    UIView.animate(withDuration: 0.2, animations: 
        view.center = CGPoint(x: self.view.bounds.midX , y: self.view.bounds.midY + 50)
    , completion: (finished) -> Void in
        UIView.animate(withDuration: 0.1, animations: 
            view.center = CGPoint(x: self.view.bounds.midX , y: self.view.bounds.midY )

        )


    )

popView 显示正确,但 contentView 不响应点击手势。为什么??请帮帮我~

【问题讨论】:

【参考方案1】:

在 popView 的视图控制器而不是 contentview 上添加点击手势。它将按如下方式工作。

let recognizer = UITapGestureRecognizer(target: self, action: #selector(self.hide(_: )))
        recognizer.numberOfTapsRequired = 1
        popView.view.addGestureRecognizer(recognizer)
        print(String(describing: popView.view.gestureRecognizers))

还将您的隐藏功能移动到按钮操作类中。隐藏并显示到该类本身,如下所示。

func hide(_ recognizer: UITapGestureRecognizer)
        self.popView.view.removeFromSuperview()

        let rootView = UIApplication.shared.keyWindow! as UIWindow
        rootView.addSubview(self.view)


    

我希望这会有所帮助。

下面是我的 PopView 类代码:

import UIKit

class PopView: UIViewController 

    var baseView: UIView = UIView()
    var contentView: UIView = UIView()
    var headView: UIView = UIView()
    var headImageView: UIImageView = UIImageView()


    override func viewDidLoad() 
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        self.setup()
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    

    func setup()
        view.frame = UIScreen.main.bounds

        baseView.frame = view.frame
        baseView.backgroundColor = UIColor.black
        //baseView.alpha = appearence.backgroundAlpha
        view.addSubview(baseView)

        contentView.backgroundColor = UIColor.white
        contentView.layer.cornerRadius = 0.5
        contentView.frame = CGRect(x: 10, y: 10, width: 200, height: 200)
        contentView.layer.masksToBounds = true
        contentView.center = CGPoint(x: self.view.bounds.midX , y: self.view.bounds.midY )


        baseView.addSubview(contentView)

        headView.frame = CGRect(x: 0, y: 0, width: contentView.bounds.width, height: contentView.bounds.height / 2)
        headView.backgroundColor = UIColor.yellow
        contentView.addSubview(headView)



        headImageView.image = UIImage(named: "patternsPlaceholder")
        headImageView.contentMode = .center
        headImageView.frame.size = headImageView.image!.size
        headImageView.center = CGPoint(x: headView.bounds.midX, y: headView.bounds.midY)
        headView.addSubview(headImageView)

    

    func setVisible()
        let rootView = UIApplication.shared.keyWindow! as UIWindow
        rootView.addSubview(self.view)

    

    func animateView(view: UIView)
        view.center = CGPoint(x: self.view.bounds.midX, y: self.view.bounds.minY - view.bounds.midY)
        UIView.animate(withDuration: 0.2, animations: 
            view.center = CGPoint(x: self.view.bounds.midX , y: self.view.bounds.midY + 50)
        , completion: (finished) -> Void in
            UIView.animate(withDuration: 0.1, animations: 
                view.center = CGPoint(x: self.view.bounds.midX , y: self.view.bounds.midY )

            )


        )
    



    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    
    */


下面是我的 baseviewController 代码。

import UIKit

class ViewController: UIViewController 

    var popView = PopView()

    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    

    @IBAction func popViewButtonAction(_ sender: Any) 

//        let popView = PopView()
        popView.setVisible()
        popView.animateView(view: popView.contentView)

        let recognizer = UITapGestureRecognizer(target: self, action: #selector(self.hide(_: )))
        recognizer.numberOfTapsRequired = 1
        popView.view.addGestureRecognizer(recognizer)
        print(String(describing: popView.view.gestureRecognizers))

    

    func hide(_ recognizer: UITapGestureRecognizer)
        self.popView.view.removeFromSuperview()

        let rootView = UIApplication.shared.keyWindow! as UIWindow
        rootView.addSubview(self.view)


    




我希望它会给你灵感。

谢谢, 尚卡尔

【讨论】:

thanku!!!还有一件事,你知道为什么我把代码放在popview里面不起作用吗 您正在设置内容视图框架,我猜这是非常小的区域,很难在整个屏幕上找到可点击的区域,您可以增加内容视图的大小,或者您可以做任何我给出的解决方案。

以上是关于UITapGestureRecognizer 在属于另一个控制器的视图中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

使用 UITapGestureRecognizer 无法识别的选择器

UIlabel 中的 UITapGestureRecognizer 错误

UITapGestureRecognizer 的问题

带有点击事件的 UITapGestureRecognizer

UIButton 上的 UITapGestureRecognizer

为啥 UIButton 会覆盖 UITapGestureRecognizer?