按钮锚定到InputAccessoryView仅在其框架中工作
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了按钮锚定到InputAccessoryView仅在其框架中工作相关的知识,希望对你有一定的参考价值。
建立
我通过以下方式在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
属性) - 当我这样做时,
photoButton
部分隐藏在inputAccessoryView
背后,我无法用view.bringSubview(ToFront:)
推进它
提前致谢。
在过去的几天里,我在自己的工作中遇到了这个问题。
你需要为你的hitTest
实现自己的inputAcessoryView
UIResponder方法。可能看起来像这样的东西:
override func hitTest(_ point: CGPoint,
with event: UIEvent?) -> UIView? {
if self.photoButton.frame.contains(point) {
return self.photoButton
}
return super.hitTest(point, with: event)
}
更多信息可以看到in this related question。
你有的问题是inputAccessoryView
(你的bottomBarView
)没有高度。因此,您添加的所有子视图都超出了它的范围。如果你要设置clipsToBounds = true
,你会发现一切都消失了。
正如您所看到的,这个问题是,这些子视图没有获得触摸事件,因为它们超出了超级视图的范围。来自Apple的文档:
如果触摸位置位于视图边界之外,则hitTest:withEvent:方法将忽略该视图及其所有子视图。因此,当视图的clipsToBounds属性为NO时,即使它们恰好包含触摸,也不会返回该视图边界之外的子视图。
Understanding Event Handling, Responders, and the Responder Chain
解决方案是让inputAccessoryView
成为正确的高度。 self.view.frame.height / 9
在你的例子中是0
,因为在你使用它时没有设置框架。
相反,创建一个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)
}
}
尝试添加按钮。你会看到它现在得到一个触摸事件,因为它现在在它的超级视图范围内。
以上是关于按钮锚定到InputAccessoryView仅在其框架中工作的主要内容,如果未能解决你的问题,请参考以下文章