为什么NSLayoutAttributeCenterX以0为中心而不是容器视图中心?

时间:2014-12-25 22:34:11

标签: ios centering nslayoutconstraint

我遇到了NSLayoutAttributeCenterX的问题,我无法弄清楚。 我为自定义视图创建了一个NIB,在这个自定义视图中,我插入了一个我想要在x轴中心的UILabel。然后我在我的根ViewController视图中插入此自定义视图。 现在,我重写了自定义视图的“layoutSubviews”方法,将我的约束放在那里,使Label在自定义视图中居中。 我在这个视图“appTitle”中调用了UILable。 以下是我的自定义视图的“layoutSubviews”方法的内容。正如您在那里看到的,我使用以下约束方法将UILabel置于自定义视图的中心,在x轴上。

NSLayoutConstraint  *titleConstraint_H = [NSLayoutConstraint constraintWithItem:self.appTitle attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1 constant:0];

但是,最终结果是UILabel以x = 0为中心,而不是x = 160,这是包含它的自定义视图的中心。我不明白为什么会这样。 在我的模拟中,我在PORTRAIT MODE中使用ipHone 5s,我将自定义视图的宽度设置为等于手机帧的宽度,即320.因此x = 160是中心的x坐标点。

  • 以下是“layoutSubviews”
  • 中的代码
  • LLDB输出,显示约束生效后appTitle标签的中心(po(CGPoint)[self.appTitle center])
  • LLDB输出,显示包含标签“appTitle”的自定义视图的中心(po(CGPoint)[self center])
  • 和最终输出

我想知道是否有人遇到过这个问题并且已经弄明白了

- (void)layoutSubviews {



//######### TITLE ####################################

UIFont *font = [UIFont fontWithName:@"Avenir-Black" size:20.0];
UIColor *color = [UIColor blackColor];

NSDictionary *attrsDictionary = [NSDictionary dictionaryWithObjects:@[font,color] forKeys:@[NSFontAttributeName,NSForegroundColorAttributeName]];

NSAttributedString *titleString = [[NSAttributedString alloc] initWithString:@"WHINE-O-METER" attributes: attrsDictionary];
self.appTitle.attributedText = titleString;

// Adjust UILabel  frame to size of text
[self.appTitle sizeToFit];

// Center title on horizontal length
NSLayoutConstraint  *titleConstraint_H = [NSLayoutConstraint constraintWithItem:self.appTitle attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1 constant:0];


NSDictionary *viewsDictionary = @{ @"title":self.appTitle};
NSArray *titleConstraint_V = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[title]-20-|" options:0 metrics:nil views:viewsDictionary];

[self addConstraints:titleConstraint_V];
[self addConstraint:titleConstraint_H];

}

enter image description here

enter image description here

谢谢!

2 个答案:

答案 0 :(得分:0)

很多代码可以在xib文件中更轻松地完成。我的建议是删除所有代码并使用自动布局在xib中设置它。如果您使用自动布局,请不要调用sizeToFit,只需在包含文本的标签上设置前导和尾随约束。您不需要实现layoutSubviews来实现此目的。

答案 1 :(得分:0)

您不应该在-layoutSubviews中添加或修改约束。来自docs

  

只有当子视图的自动调整和基于约束的行为不提供您想要的行为时,才应覆盖此方法。

相反,您应该在覆盖-updateConstraints时设置约束。当你覆盖这样的方法时,不要忘记调用super。 (这可能实际上也会导致您的问题。您对-layoutSubviews的覆盖不会调用super。)