NSLayoutConstraint并确定哪个子视图更宽
我在子类容器UIView
创build一个UISwitch
和一个UILabel
:
UISwitch *toggleSwitch = [UISwitch new]; toggleSwitch.translatesAutoresizingMaskIntoConstraints = FALSE; [toggleSwitch addTarget:self action:@selector(switchToggleDetected:) forControlEvents:UIControlEventValueChanged]; self.toggleSwitch = toggleSwitch; [self addSubview:toggleSwitch]; UILabel *label = [UILabel new]; label.translatesAutoresizingMaskIntoConstraints = FALSE; label.textAlignment = NSTextAlignmentCenter; label.textColor = [UIColor whiteColor]; label.font = [UIFont fontWithName:HELVETICA_FONT_STYLE_BOLD size:10.0]; label.text = [self.text uppercaseString]; self.label = label; [self addSubview:label]; [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[toggleSwitch]-5-[label]" options:NSLayoutFormatAlignAllCenterX metrics:nil views:NSDictionaryOfVariableBindings(toggleSwitch, label)]]; [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[toggleSwitch]|" options:NSLayoutFormatAlignAllCenterY metrics:nil views:NSDictionaryOfVariableBindings(toggleSwitch, label)]]; [self addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:label attribute:NSLayoutAttributeRight multiplier:1 constant:0]]; [self addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:label attribute:NSLayoutAttributeBottom multiplier:1 constant:0]];
这给了我这个:
最后两个约束让我给容器视图一个“固有的大小”。 容器将是rect(0,0,0,0)。 然后我告诉右边的宽度应该与UILabel
宽度相同,底部应该和UILabel
的高度一样。
我可能会遇到的问题是当标签比开关短时:
这将导致交换机容器视图未正确放置的问题:
[contentImageView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-5-[toggleView]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(toggleView)]];
所以我想把约束条件放在两者中较长的一个上,不pipe是开关还是标签,但我不确定如何确定哪个更宽。 开关是一个恒定的宽度,但我不能获得标签的宽度,直到添加到屏幕后,这是为时已晚。
我试着添加[self layoutIfNeeded]
和[label layoutIfNeeded]
:
[self layoutIfNeeded]; [label layoutIfNeeded]; DLog(@"label: %@", label); DLog(@"switch: %@", toggleSwitch); //Constraints added here
结果:
DEBUG | -[SwitchContainerView createContainerSwitch] | label: <UILabel: 0x7af7c6d0; frame = (0 0; 0 0); text = 'ON'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7af7c7b0>> DEBUG | -[SwitchContainerView createContainerSwitch] | switch: <UISwitch: 0x7af7b370; frame = (0 0; 51 31); layer = <CALayer: 0x7af7b430>>
有关确定哪一个更宽的build议?
您不需要“确定哪个更宽”,只需设置约束条件,然后走开,让自动布局工作。 简单地使用两个不等式/优先级约束来确定包含超级视图相对于两个子视图的宽度。
我只用约束来实现这个安排 – 我现在所做的就是改变标签的文字:
每当标签文本短,超视图比开关宽20点。 每当标签文字很长时,超视图比标签宽20点。 这完全是由约束configuration的。 以下是确定屏幕截图中黄色超级视图宽度的约束(如debugging器控制台中所示):
UIView:0x7fdb03435450.width >= UISwitch:0x7fdb034355c0.width + 20 priority:999 UIView:0x7fdb03435450.width >= UILabel:0x7fdb03433260'Infundibulum'.width + 20 priority:999
约束不会改变; 我设置了一次,布局正常,并随着标签文本的变化而继续工作。