iOS自动布局和UIToolbar/UIBarButtonItems

24
我有一个启用了自动布局的iOS视图,并带有一个包含UISearchBarUISegmentControlUIToolbar 。 我希望UISearchBar具有灵活的宽度,因此需要添加约束来强制执行此操作,但是据我所知,您无法在接口构建器中向UIToolbar中的项目添加约束。 所有选项都被禁用。

AutoLayout之前,我会使用autoresizingmasks来完成此操作。

UIToolbars/UINavigationBars内不允许使用约束吗?

在使用自动布局时,还可以通过什么其他方式实现这一点?


我以前做过类似的事情,不过基本上我只是等待视图大小改变,然后相应地更新目标视图的框架。如果没有自动完成的方法,这总是一个选择。 - Brian
你能发一张图片吗? - Vaibhav Saran
我本来想用AutoLayout,但最终放弃了,回归使用autoresizingmasks。这种模式下效果很好。 - outerstorm
@Brian 你建议如何观察视图大小的变化? - devios1
1
@devios 不确定你的使用场景,但 layoutSubViews 很可能是你想要的。当方向改变时等情况下,它会被调用。https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/index.html - Brian
3个回答

26

自动布局约束只适用于UIViews及其子类。

虽然UIToolbar允许某些基于UIView的项目(例如UISearchBarUISegmentedControl),但它们可能必须与不继承UIViewUIBarButtonItems共存。

在自动布局可以使用UIBarButtonItems之前,请像您已经做的那样进行操作。

您的另一选择是使用仅基于UIViews的小部件制作自己的工具栏。


4
苹果公司是否正在努力解决这个问题?如果我在不同的地方必须使用AL和旧方法,就会让我感到困扰,因为这种不一致性已经被打破了... - Petar

9
这也可以直接从storyboard中完成。只需在工具栏中拖放项目,并将其中一些转换为可伸缩或固定空间,即可获得所需效果。请参见下面的两个示例。

Evenly spaced

Centered

NB: 这是我对Aligning UIToolBar items的回答的副本,我在寻找这样的解决方案时偶然发现了这两个问题。


7

你可以在代码中完成这个操作。我经常不使用Interface Builder,转而用代码。当添加或调整约束时,IB 似乎更多地成为我的绊脚石。下面是在我自定义的 UIToolbar 子类的 -initWithFrame: 方法中所做的事情。

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        [self addSubview:self.label];

        [self addConstraint:[NSLayoutConstraint
                             constraintWithItem:self.label
                             attribute:NSLayoutAttributeCenterX
                             relatedBy:NSLayoutRelationEqual
                             toItem:self
                             attribute:NSLayoutAttributeCenterX
                             multiplier:1 constant:0]];
        [self addConstraint:[NSLayoutConstraint
                             constraintWithItem:self.label
                             attribute:NSLayoutAttributeCenterY
                             relatedBy:NSLayoutRelationEqual
                             toItem:self
                             attribute:NSLayoutAttributeCenterY
                             multiplier:1 constant:0]];
    }
    return self;
}

由于我尽可能地喜欢懒加载,所以这是我的self.label实例变量(在上面的[self addSubview:self.label]被调用时调用)。

- (UILabel *)label {
    if (_label) return _label;
    _label = [UILabel new];
    _label.translatesAutoresizingMaskIntoConstraints = NO;
    _label.textAlignment = NSTextAlignmentCenter;
    return _label;
}

对我来说似乎起作用了。不过,我没有添加任何UIBarButtonItems,所以可能会有差异。


如果您正在尝试使用约束重新定位现有的工具栏,您会发现NSLayoutAttributeCenterX约束非常有用。 - russes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接