iOS11 UIToolBar内容视图
在iOS11 UIToolBar内容视图,ios,uitoolbar,ios11,Ios,Uitoolbar,Ios11,在ios11中,按钮和文本字段是UIToolBar的子视图,没有响应。将视图层次结构与iOS 10进行比较,我们发现在UIToolBar的所有子视图上都有一个\u UIToolBarContentView 例如,UIToolBar的这个新布局打破了slacktextviewcontroller 需要在iOS 10/11中运行的解决方案有一种奇怪的方法 [self.textInputbar sendSubviewToBack:[self.textInputbar.subviews lastObj
ios11
中,按钮和文本字段是UIToolBar
的子视图,没有响应。将视图层次结构与iOS 10进行比较,我们发现在UIToolBar
的所有子视图上都有一个\u UIToolBarContentView
例如,UIToolBar
的这个新布局打破了slacktextviewcontroller
需要在iOS 10/11中运行的解决方案有一种奇怪的方法
[self.textInputbar sendSubviewToBack:[self.textInputbar.subviews lastObject]];
要解决
iOS11
(与较低版本兼容)的问题,您只需
在将UIToolBar
作为子视图添加到UI层次结构之后立即创建layoutSubview
在这种情况下,\u UIToolbarContentView
会降低到UIToolBar的第一个子视图,您可以
像以前一样将所有子视图添加到更高的位置
例如,在ObjC
中
UIToolbar *toolbar = [UIToolbar new];
[self addSubview: toolbar];
[toolbar layoutIfNeeded];
<here one can add all subviews needed>
UIToolbar*工具栏=[UIToolbar新建];
[自添加子视图:工具栏];
[需要工具栏布局];
同样的问题也发生在上,您只需使用
hitTest(:with:)
方法即可
UIToolbar
中创建属性contentView
:
open private(set) var contentView: UIView = UIView()
contentView
的框架与UIToolbar
的框架相同。例如:
contentView.frame = bounds
contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
addSubview(contentView)
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
}
}
在这种情况下,如果您想通过简单地添加其他视图来自定义工具栏,您应该将它们添加到
contentView
,这样它们将被正确定位。我已经解决了这个问题。我在UIToobar的子类中重写了layoutSubviews
方法,并将\u UIToolbarContentView
的userInteractionEnable
更改为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;
}
}
}
新的
UIToolbar
对象主动使用基于约束的布局,因此最好重写-(void)updateConstraints
方法。要在UIToolbar
对象上显示自定义视图,最好将其子类化并添加自定义容器视图:
- (UIView *)containerView
{
if (_containerView) {
return _containerView;
}
_containerView = [[UIView alloc] initWithFrame:self.bounds];
_containerView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
return _containerView;
}
现在,您可以安全地将自定义视图添加到容器视图中。要使自定义视图具有响应性,我们需要在约束更新后更改工具栏子视图的顺序:
- (void)updateConstraints
{
[super updateConstraints];
[self bringSubviewToFront:self.containerView];
}
请注意,如果您将
UINavigationController
与自定义工具栏一起使用,则应在添加自定义子视图之前强制它更新其布局。在仅使用autolayout和代码的Swift中,对我有效的方法是在添加项之前,但在设置约束之后,执行前面提到的布局
- 实例化工具栏
- 将其添加到您的视图中
- 添加约束条件 toolbar.layoutIfNeeded() toolbar.setItems([…(您的项目)],动画:true)
UIToolBar
的layoutSubviews
方法,要么将无响应的视图放在前面,要么将最后一个视图放在覆盖的后面。这实际上是一个很好的问题。没有关闭的理由。要找出iOS 10/11之间的差异需要时间和研究。谢谢你,我也遇到了同样的问题。我认为这个问题很清楚,足以说明这个问题。我们应该重新打开这个问题什么是“textInputbar”?textInputbar是UIToolbar的一个对象。这是为什么只在SlackTextViewController
的上下文中描述的解决方案,这是一个与UIToolBar
相关的一般问题。无论如何,即使我将lastObject
带到front@gran33请参阅下面的工作补丁。我也有同样的问题。如果我们在界面生成器中添加视图会怎么样?除了把它们送到前线,还有别的解决办法吗?谢谢。遇到了同样的问题。我使用故事板添加了UIToolBar,如何解决此问题。@anamika41当我尝试通过xib向工具栏添加文本字段或按钮时,元素会自动包装为BarButtonim。所以我可以触摸这些元素,也可以检查toolbarContentView是否在这些元素的下方工作。另外,如果我在viewDidLoad上添加一个按钮,从xib加载到工具栏,它在触摸屏上也可以正常工作。我的UIToolbar是故事板的一部分。UIToolbar及其子项(按钮)在视图控制器中被引用。我无法访问它们,因为在运行时它们会被\u UIToolbarContentView
遮挡,我不确定应该如何处理它。我没有使用xib,也没有在代码中创建它。