1

设置

我通过以下方式实现了inputAcessoryView一个:UIViewController

override var inputAccessoryView: UIView? {

    get {

        return bottomBarView
    }
}
override var canBecomeFirstResponder: Bool {

    return true
}

fileprivate lazy var bottomBarView: UIView = {

    let view = UIView()
    let separatorLineView = UIView()

    view.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height / 9)
    view.backgroundColor = .white

    /...

    separatorLineView.backgroundColor = UIColor(r: 220, g: 220, b: 220, a: 1)
    separatorLineView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(separatorLineView)
    separatorLineView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
    separatorLineView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    separatorLineView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
    separatorLineView.heightAnchor.constraint(equalToConstant: 1).isActive = true

    view.addSubview(self.photoButton)
    self.photoButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    self.photoButton.centerYAnchor.constraint(equalTo: separatorLineView.centerYAnchor, constant: -12).isActive = true
    self.photoButton.widthAnchor.constraint(equalToConstant: view.frame.width / 4.5).isActive = true
    self.photoButton.heightAnchor.constraint(equalToConstant: view.frame.width / 4.5).isActive = true

    return view
}()

photoButton对 执行操作.touchUpInside

问题

该按钮只能在包含在inputAccessoryView框架中的部分中单击:如果我在外面的部分上单击它,则不会发生任何事情。

有什么快速的方法让它像这样工作吗?

但是,我尝试将其photoButton移出bottomBarView并将其添加到视图中:

  • 我需要photoButton被“锚定”到inputAccessoryView,但似乎inputAccessoryView在视图中没有锚属性?(我只能frame通过 bang unwrapping 访问它们的属性)
  • 当我这样做时,photoButton部分隐藏在后面inputAccessoryView,我无法将其带入view.bringSubview(ToFront:)

提前致谢。

4

2 回答 2

1

您遇到的问题是inputAccessoryViewbottomBarView为您)没有高度。因此,您添加的所有子视图都超出了它的范围。如果你要设置clipsToBounds = true,你会看到一切都消失了。

正如您所看到的,问题在于这些子视图没有收到触摸事件,因为它们超出了它们的超级视图的范围。来自 Apple 的文档:

如果触摸位置在视图边界之外,则 hitTest:withEvent: 方法会忽略该视图及其所有子视图。因此,当视图的 clipsToBounds 属性为 NO 时,即使碰巧包含触摸,也不会返回该视图边界之外的子视图。

了解事件处理、响应者和响应者链

解决方案是获得inputAccessoryView正确的高度。self.view.frame.height / 90您的示例中,因为在您使用框架时尚未设置框架。

相反,创建一个UIView包含以下重要部分的子类:

class BottomBarView: UIView {

    init(frame: CGRect) {
        super.init(frame: frame)

        autoresizingMask = .flexibleHeight

        let someView = UIView()
        addSubview(someView)
        someView.translatesAutoresizingMaskIntoConstraints = false
        someView.topAnchor.constraint(equalTo: topAnchor).isActive = true
        someView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
        someView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
        someView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true

        // In this case, the top, bottom, and height constraints will 
        // determine the height of the inputAccessoryView
        someView.heightAnchor.constraint(equalToConstant: 100).isActive = true
    }

    override var intrinsicContentSize: CGSize {
        return CGSize(width: UIViewNoIntrinsicMetric, height: 0)
    }
}

尝试添加一个按钮。你会看到现在它得到了一个触摸事件,因为它现在在它的超级视图的范围内。

于 2018-01-03T10:40:52.313 回答
0

在过去的几天里,我自己在自己的工作中遇到了这个问题。

您需要hitTest为您的inputAcessoryView. 可能看起来像这样的东西:

override func hitTest(_ point: CGPoint, 
        with event: UIEvent?) -> UIView? {

    if self.photoButton.frame.contains(point) {
        return self.photoButton
    }

    return super.hitTest(point, with: event)
}

更多信息可以在这个相关问题中看到。

于 2017-03-03T09:35:21.210 回答