UILabel在第一个基线与UITextField对齐在文本字段成为第一个响应者之前不起作用(得到键盘)

时间:2015-03-21 18:23:01

标签: ios uitextfield autolayout baseline

我在各种不同的设置中遇到了这个问题,包括IB和手动定义约束。这是当前设置:

我在容器视图中有一个标签和一个文本字段,使用以下可视格式约束:

H:|-(4)-[label(labelWidth)]-(4)-[editor]-(4)-|
option = NSLayoutFormatAlignAllFirstBaseline

V:|-(4)-[editor]-(4)-|

对于这些约束,标签位于屏幕左上角的容器视图外部(实际位于导航栏下方)。

当我添加这些约束时:

V:|-(>=4)-[label]-(>=4)-|

标签位于距离顶部4pt处(与新约束匹配)。

在这两种情况下,一旦我点击文本字段打开键盘然后再次关闭它(不需要进行任何更改),标签就会正确地与文本字段基线对齐。

[编辑:添加了一些截图] 初始状态:

Initial state

打开键盘:

Keyboard opened

键盘关闭后正确显示:

After closing the keyboard

在Xcode调试器中,基准约束在打开和关闭键盘之前显示为非活动状态,并在键盘打开和关闭后显示为活动状态。

在第一次编辑之前,似乎没有(正确地)计算文本字段的基线。使用nil初始化文本字段,@""或者某些文字不会影响行为。

问题是,导致这种行为的是什么,更重要的是,我该怎么办?

1 个答案:

答案 0 :(得分:0)

如果以编程方式创建文本字段,或者IB未添加基线对齐约束,则文本字段基线视图未正确定位。

在适当的时候调用[textField setNeedsUpdateConstraints](见下文)解决了这个问题。

在我的情况下,我有一个自定义容器视图,它添加/替换约束以将标签布局为文本字段。我不得不在容器视图的layoutSubviews方法中调用[textField setNeedsUpdateConstraints]。在updateConstraints中调用约束的地方没有帮助。

在类似的情况下,文本字段已经有一个基线对齐(任何视图,标签或另一个),它将被新的基线对齐替换,问题不会发生,显然是因为IB会以某种方式照顾及时布置参与文本字段。

所以我的解决方法/解决方案是:

- (void)updateConstraints {
  // setup constraints for affected views in self.viewsDictionary
  [super updateConstraints];
}

- (void)layoutSubviews {
  [super layoutSubviews];
  for (UIView* view in self.viewDictionary.objectEnumerator) {
    [view setNeedsUpdateConstraints];
  }
}