[英]iOS11 UIToolBar Contentview
In iOS 11
buttons and text field are unresponsive being subviews of UIToolBar
.在
iOS 11
按钮和文本字段作为UIToolBar
子视图没有响应。 Comparing view hierarchy to iOS 10
we see there is a _UIToolBarContentView
over all subview of UIToolBar
.将视图层次结构与
iOS 10
进行比较,我们看到_UIToolBarContentView
的所有子视图上UIToolBar
一个UIToolBar
。
For instance, this new layout of the UIToolBar
breaks slacktextviewcontroller
https://github.com/slackhq/SlackTextViewController/issues/604例如,
UIToolBar
这个新布局打破了slacktextviewcontroller
https://github.com/slackhq/SlackTextViewController/issues/604
Need a solution working in iOS 10/11
.需要一个适用于
iOS 10/11
的解决方案。
To solve the problem for iOS11
(compatible with lower versions) you only need to make layoutSubview
right after UIToolBar
was added as a subview to UI hierarchy.为了解决
iOS11
(兼容低版本)的问题,你只需要在UIToolBar
作为子视图添加到UI层次结构后UIToolBar
制作layoutSubview
。
In this case _UIToolbarContentView
lowers to the first subview of UIToolBar, and you can add all your subviews higher as before.在这种情况下
_UIToolbarContentView
降低到_UIToolbarContentView
的第一个子视图,您可以像以前一样将所有子视图添加到更高的位置。
For example in ObjC
,例如在
ObjC
,
UIToolbar *toolbar = [UIToolbar new];
[self addSubview: toolbar];
[toolbar layoutIfNeeded];
<here one can add all subviews needed>
The same problem happens with slacktextviewcontroller slacktextviewcontroller 也会出现同样的问题
I have solved this problem in my case.我已经解决了这个问题。 I rewrite the
layoutSubviews
method in subclass of UIToobar and change the userInteractionEnable
of _UIToolbarContentView
into NO.我在 UIToobar 的子类中重写了
layoutSubviews
方法,并将 _UIToolbarContentView 的userInteractionEnable
_UIToolbarContentView
为 NO。
- (void)layoutSubviews {
[super layoutSubviews];
NSArray *subViewArray = [self subviews];
for (id view in subViewArray) {
if ([view isKindOfClass:(NSClassFromString(@"_UIToolbarContentView"))]) {
UIView *testView = view;
testView.userInteractionEnabled = NO;
}
}
}
You can just use the hitTest(_:with:)
method.您可以只使用
hitTest(_:with:)
方法。
First, create a property contentView
in UIToolbar
:首先,在
UIToolbar
创建一个属性contentView
:
open private(set) var contentView: UIView = UIView()
Then, make the contentView
's frame the same as the UIToolbar
's.然后,使
contentView
的框架与UIToolbar
的框架相同。 For example:例如:
contentView.frame = bounds contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight] addSubview(contentView)
Finally, override the hitTest(_:with:)
method:最后,覆盖
hitTest(_:with:)
方法:
open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { if self.point(inside: point, with: event) { if let hitTestView = contentView.hitTest(point, with: event) { return hitTestView } else { return self } } else { return nil } }
In this situation, if you want to customize a toolbar by simply adding additional views, you should add them to the contentView
so they will be positioned appropriately.在这种情况下,如果您想通过简单地添加其他视图来自定义工具栏,您应该将它们添加到
contentView
以便它们被适当地定位。
The new UIToolbar
object actively uses layout based on constraints, so it is better to override - (void)updateConstraints
method.新的
UIToolbar
对象主动使用基于约束的布局,所以最好重写- (void)updateConstraints
方法。 To present custom views over UIToolbar
object it is better to subclass it and add custom container view:要在
UIToolbar
对象上显示自定义视图,最好将其子类化并添加自定义容器视图:
- (UIView *)containerView
{
if (_containerView) {
return _containerView;
}
_containerView = [[UIView alloc] initWithFrame:self.bounds];
_containerView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
return _containerView;
}
Now you can safely add your custom views to the container view.现在您可以安全地将自定义视图添加到容器视图中。 To make the custom views responsive we need change the order of toolbar subviews after the constraints update:
为了使自定义视图具有响应性,我们需要在约束更新后更改工具栏子视图的顺序:
- (void)updateConstraints
{
[super updateConstraints];
[self bringSubviewToFront:self.containerView];
}
Note, that if you are using UINavigationController
with custom toolbar, you should force it to update its layout before adding your custom subviews.请注意,如果您将
UINavigationController
与自定义工具栏一起使用,则应在添加自定义子视图之前强制它更新其布局。
In Swift with autolayout and code only, what worked for me was to do layout as malex mentions just before adding items, but after setting constraints.在仅具有自动布局和代码的 Swift 中,对我有用的是在添加项目之前但在设置约束之后按照malex提到的方式进行布局。
Add constraints添加约束
toolbar.layoutIfNeeded()工具栏.layoutIfNeeded()
toolbar.setItems([... (your items)], animated: true)工具栏.setItems([... (你的物品)], 动画: 真)
有一种奇怪的方法可以做到这一点。
[self.textInputbar sendSubviewToBack:[self.textInputbar.subviews lastObject]];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.