【问题标题】:Alternative ways for handling keyboard dismissal when either child or parent view controller is tapped?当点击子视图控制器或父视图控制器时,处理键盘关闭的替代方法?
【发布时间】:2018-08-06 08:36:45
【问题描述】:

我有一个具有 UITextField 的子视图控制器。我还有一个父视图控制器,我在其中添加了一个子视图控制器。子视图控制器占据了大约一半的父视图控制器。

self.childVC = ChildViewController()
self.childVC.delegate = self 

func addChildViewController () {
self.addChildViewController(self.childVC)
self.childVC.view.frame = CGRect(x: x, y: y, width: widthOfContainerView, height: heightOfContainerView)
self.view.addSubview(self.childVC.view)
self.childVC.didMove(toParentViewController: self)
}

当用户点击 UITextField 时,我会显示一个键盘,并且我希望每当用户点击文本字段外部时关闭键盘 - 这将在子视图控制器的视图内,或者父视图控制器的视图。

现在我在两个子视图控制器和父视图控制器中设置了一个点击手势识别器来实现这一点。

func setupTapGestureRecognizer() {
let tap = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
view.addGestureRecognizer(tap)
view.isUserInteractionEnabled = true
}

@objc func handleTap(_ sender: UITapGestureRecognizer) {
    view.endEditing(true)
}

作为一个初学者,我怀疑在我的项目中包含这样的冗余代码并不是一个好习惯,但我想不出任何其他方法来处理这个问题。

还有哪些其他方法可以确保无论用户是在子视图还是父视图中点击,在文本字段外点击都会关闭键盘?

谢谢。

【问题讨论】:

  • 我认为如果你只在父视图控制器上添加点击手势并设置 userInteraction 启用它仍然可以在任一视图控制器视图上点击,唯一的问题是你的子视图控制器不应该有手势可以采取行动,这意味着如果孩子无法处理,则将手势传递给父母。我没试过。请让我知道这是否有效。 :-)

标签: ios swift keyboard uitextfield


【解决方案1】:

5 年过去了,这仍然是我必须处理的 iOS 最烦人的方面之一。不幸的是,我个人还没有看到处理所有问题的直接方法,但这是我的方法 FWIW:

首先,我倾向于使用包罗万象的方法,而不是弄乱view.endEditing 或手动辞去各个项目的第一响应者: UIApplication.shared.sendAction(Selector(resignFirstResponder), to: nil, from: nil, for: nil).

这很容易处理一般情况,以及第一响应者(在您的示例中为TextField)可能与被点击的视图不在同一个视图堆栈中的情况。这也有助于以您喜欢的任何方式将其添加为 extension

除此之外,它实际上是为了最大限度地扩大您的tapGestures 的覆盖范围。以下是我使用的一些选项:

  • 正如@IraniyaNaynesh 所提到的,摆弄userInteractionEnabled 让水龙头进入处理所有内容的下层。
  • 创建UIViewUILabel 等的子类,以自动处理点击以调用resignFirstResponder
  • 在编辑TextField 时动态添加/删除一组清晰视图。 (不理想,但在某些情况下我发现这是最简单的解决方案)。

希望那里的某个人(或 Apple)可以为此想出一个更简单的解决方案!

【讨论】:

    【解决方案2】:

    当您加载子视图控制器并将其视图添加为“父”视图控制器的子视图时,该视图将成为父视图层次结构的一部分。

    可以简单地使用touchesBegan(),而不是添加标签识别器。

    在“父”VC中,添加:

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        view.endEditing(true)
    }
    

    这将通过触摸“子视图”“父视图”中的任意位置触发。而且,由于子视图中的文本字段也是视图层次结构的一部分,这将关闭键盘。

    这显示了与嵌入式 VC 的关系(使用 Storyboard 中的 Container View),但通过代码加载时将具有相同的行为:

    触摸蓝色“子视图”或白色“父视图”中的任意位置将触发父 VC 中的touchesBegan

    【讨论】:

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