【问题标题】:Dismiss UIView within ViewController by tapping outside of UIView通过在 UIView 之外点击来关闭 ViewController 中的 UIView
【发布时间】:2021-04-09 21:37:00
【问题描述】:

我在我的 ViewController 上展示了一个 UIView,它包含一个覆盖整个视图控制器的表视图。我想在 UIView 之外点击时关闭 UIView,但没有找到任何有助于解决问题的方法。这就是我想要做的,它应该可以工作,但即使没有显示 UIView,它也不会注册触摸。有人处理过类似的问题吗?

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let touch: UITouch? = touches.first

        if touch?.view != fullSessionView {
            fullSessionView?.removeFromSuperview()
        }
    }

【问题讨论】:

  • 小批评?如果允许我的话?您提出UIView。此视图通常是UIViewController 的一部分。 (想想 MVC。)字面上不可能呈现“覆盖整个视图控制器的表视图”。这种描述一直在发生。在你的情况下?这可能很重要……您越早了解视图与其控制器之间的区别,您就越容易了解操作系统在何处处理点击。
  • 如果视图覆盖了整个屏幕,则在导航栏上添加一个按钮以将其关闭。

标签: ios swift uiview touchesbegan


【解决方案1】:

首先,我会尝试看看是否有任何内置的presentation styles 可以为您工作。但是您必须将视图嵌入到视图控制器中。

如果您想坚持使用UIView,您可以尝试在覆盖整个屏幕的透明背景UIView 上显示您的UIView,并将UIGestureRecognizer 附加到透明背景。

点击背景会触发回调(通过委托、关闭等),然后会删除您的视图。

【讨论】:

    【解决方案2】:

    你应该总是打电话给super,像这样:

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event) /// always call the super
    

    但无论如何,您想查看fullSessionView 是否包含触摸。因此,您可能不想检查发生触摸的视图,而是希望检查发生触摸的 位置。像这样的:

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)
    
        let touch = touches.first
        guard let location = touch?.location(in: fullSessionView) else { return }
        if !fullSessionView.frame.contains(location) {
    
             /// tapped outside fullSessionView
             fullSessionView?.removeFromSuperview()
        }
    }
    

    【讨论】:

    • 您通常不希望视图将自己从其父视图中删除。 UIView 的职责是“管理”(即添加、调整大小、删除)其所有子视图。因此,触发器应该回调其父视图并删除有问题的视图,而不是拦截触摸以使视图自行删除。
    • @PietroRea 你确定吗?据我所知,删除子视图的唯一方法是从自身调用 removeFromSuperview...
    • 哦,我的意思是 removeFromSuperview 被调用的地方......我想我误读了你的代码。看起来父母正在移除孩子。哎呀
    【解决方案3】:

    您需要使用要添加的视图的目标和操作来初始化 UITapGestureRecognizer,如下所示:

    let tap = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
    myView.addGestureRecognizer(tap)
    Then, you should implement the handler, which will be called each time when a tap event occurs:
    @objc func handleTap(_ sender: UITapGestureRecognizer? = nil) {
        self.removefromSuperview() // this will remove added view from parent view
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多