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)


    你解决了这个问题吗?这很奇怪,但我也遇到过同样的问题,但在某些情况下它是不可见的。我尝试编辑这个问题,让你摆脱关闭状态。mods拒绝了我的编辑,因为我在编辑中包含了答案。他们说我应该回答这个问题。如果关门了,我就回答不了这个问题。无论如何,您应该覆盖
    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,也没有在代码中创建它。