iOS11 UIToolBar 内容视图

问题描述 投票:0回答:6

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

例如,

UIToolBar
的新布局打破了
slacktextviewcontroller
https://github.com/slackhq/SlackTextViewController/issues/604

需要一个适用于

iOS 10/11
的解决方案。

ios objective-c ios11 uitoolbar
6个回答
35
投票

要解决

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

在这种情况下

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

例如在

ObjC
,

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

    <here one can add all subviews needed>

同样的问题发生在slacktextviewcontroller


3
投票

我已经在我的案例中解决了这个问题。我重写了UIToobar子类中的

layoutSubviews
方法,并将
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;
         }
     }

}

1
投票

您可以使用

hitTest(_:with:)
方法。

  1. 首先,在

    contentView
    中创建属性
    UIToolbar

    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
,以便它们能够正确定位。


0
投票

新的

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
与自定义工具栏一起使用,则应在添加自定义子视图之前强制它更新其布局。


0
投票

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

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

    toolbar.layoutIfNeeded()

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


-2
投票

有一种奇怪的方法可以做到这一点。

[self.textInputbar sendSubviewToBack:[self.textInputbar.subviews lastObject]];
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.