【问题标题】:iOS11 UIToolBar ContentviewiOS11 UIToolBar 内容视图
【发布时间】:2018-02-16 20:36:12
【问题描述】:

iOS 11 中,按钮和文本字段作为UIToolBar 的子视图无响应。将视图层次结构与iOS 10 进行比较,我们看到UIToolBar 的所有子视图都有一个_UIToolBarContentView

例如,UIToolBar 的这种新布局打破了slacktextviewcontroller https://github.com/slackhq/SlackTextViewController/issues/604

需要在iOS 10/11 中工作的解决方案。

【问题讨论】:

  • 这个问题你解决了吗?
  • 这很奇怪,但我遇到了同样的问题,但在某些情况下它不可见
  • 我尝试为您编辑问题以使其脱离关闭状态。模组拒绝了我的编辑,因为我在编辑中包含了答案。他们说我应该回答这个问题。如果它已关闭,我无法回答这个问题。无论如何,您应该覆盖 UIToolBarlayoutSubviews 方法,并将无响应的视图放在前面,或者将最后一个视图发送到该覆盖内的后面。
  • 这其实是一个很好的问题。没有理由被关闭。找出 iOS 10/11 之间的区别需要时间和研究。谢谢你
  • 我也遇到了同样的问题。我认为问题很清楚,可以说明问题。我们应该重新打开这个问题

标签: ios uitoolbar ios11


【解决方案1】:

有一种奇怪的方法。

[self.textInputbar sendSubviewToBack:[self.textInputbar.subviews lastObject]];

【讨论】:

  • 什么是“textInputbar”?
  • textInputbar 是 UIToolbar 的一个对象。
  • 就是github描述的解决方案
  • 为什么只在SlackTextViewController的上下文中,这是与UIToolBar相关的一般问题。反正我把lastObject放在前面也解决不了问题
  • @gran33 请参阅下面的工作修复。我也有同样的问题。
【解决方案2】:

解决iOS11的问题(兼容低版本)你只需要 在 UIToolBar 被添加为 UI 层次结构的子视图之后立即制作 layoutSubview

在这种情况下_UIToolbarContentView 降低到 UIToolBar 的第一个子视图,你可以 像以前一样将所有子视图添加到更高的位置。

例如在ObjC

    UIToolbar *toolbar = [UIToolbar new];
    [self addSubview: toolbar];
    [toolbar layoutIfNeeded];

    <here one can add all subviews needed>

slacktextviewcontroller 也会出现同样的问题

【讨论】:

  • 如果我们在界面构建器中添加视图会怎样?除了将它们发送到前面还有其他解决方案吗?
  • 谢谢。面临同样的问题。
  • 我已经使用storyboard添加了UIToolBar,我该如何解决这个问题。
  • @anamika41 当我尝试通过 xib 将 textField 或按钮添加到工具栏中时,该元素会自动包装在 BarButtonItem 中。所以我可以触摸访问这些元素,也可以检查 toolbarContentView 是否在这些元素的下方。此外,如果我从 xib 将 viewDidLoad 上的按钮添加到工具栏中,它在触摸时也可以正常工作。
  • 我的 UIToolbar 是故事板的一部分。 UIToolbar 及其子项(按钮)在视图控制器中被引用。我无法访问它们,因为在运行时它们被_UIToolbarContentView 遮住了,我不确定我应该如何处理它。我没有使用 xib,也没有在代码中创建它。
【解决方案3】:

您可以只使用hitTest(_:with:) 方法。

  1. 首先,在UIToolbar中创建一个属性contentView

    open private(set) var contentView: UIView = UIView()
    
  2. 然后,使contentView 的框架与UIToolbar 的框架相同。例如:

    contentView.frame = bounds
    contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    addSubview(contentView)
    
  3. 最后,重写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,以便它们被适当地定位。

【讨论】:

    【解决方案4】:

    我已经解决了这个问题。我重写了UIToobar子类中的layoutSubviews方法,把_UIToolbarContentViewuserInteractionEnable改成了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;
             }
         }
    
    }
    

    【讨论】:

      【解决方案5】:

      新的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,您应该在添加自定义子视图之前强制它更新其布局。

      【讨论】:

        【解决方案6】:

        在仅具有自动布局和代码的 Swift 中,对我有用的是在添加项目之前但在设置约束之后按照 malex 提到的那样进行布局。

        • 实例化您的工具栏
        • 将其添加到您的视图中
        • 添加约束

          toolbar.layoutIfNeeded()

          toolbar.setItems([... (你的项目)], 动画: true)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-03-07
          • 1970-01-01
          • 1970-01-01
          • 2018-07-11
          • 1970-01-01
          相关资源
          最近更新 更多