NSLayoutConstraints将子视图居中

时间:2014-06-26 14:25:22

标签: ios objective-c nslayoutconstraint

我试图通过约束在其超级视图的中心设置子视图。

[view addSubview:contentView];

[view addConstraint:[NSLayoutConstraint constraintWithItem:contentView attribute:NSLayoutAttributeCenterX relatedBy:view toItem:NSLayoutRelationEqual attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]];
[view addConstraint:[NSLayoutConstraint constraintWithItem:contentView attribute:NSLayoutAttributeCenterY relatedBy:view toItem:NSLayoutRelationEqual attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]];

enter image description here

为什么这不起作用?

更多代码:

UIView *view = [UIView new];
view.translatesAutoresizingMaskIntoConstraints = FALSE;
view.backgroundColor = [UIColor orangeColor];

[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[view(180)]"
                                                             options:0
                                                             metrics:nil
                                                               views:NSDictionaryOfVariableBindings(view)]];
[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[view(100)]"
                                                             options:0
                                                             metrics:nil
                                                               views:NSDictionaryOfVariableBindings(view)]];


UIView *contentView = [UIView new];
contentView.translatesAutoresizingMaskIntoConstraints = FALSE;
contentView.backgroundColor = [UIColor blueColor];

// Create the UIButtons and UILabels and add them to contentView

[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[syncButton][syncLabel]-(10)-[doneButton][doneLabel]"
                                                                    options:NSLayoutFormatAlignAllCenterX metrics:nil
                                                                      views:NSDictionaryOfVariableBindings(syncButton, syncLabel, doneButton, doneLabel)]];

[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[syncButton]"
                                                                    options:0
                                                                    metrics:nil
                                                                      views:NSDictionaryOfVariableBindings(syncButton, doneButton)]];

[contentView addConstraint:[NSLayoutConstraint constraintWithItem:contentView
                                                        attribute:NSLayoutAttributeRight
                                                        relatedBy:NSLayoutRelationEqual
                                                           toItem:syncButton
                                                        attribute:NSLayoutAttributeRight
                                                       multiplier:1
                                                         constant:0]];

[contentView addConstraint:[NSLayoutConstraint constraintWithItem:contentView
                                                        attribute:NSLayoutAttributeBottom
                                                        relatedBy:NSLayoutRelationEqual
                                                           toItem:doneLabel
                                                        attribute:NSLayoutAttributeBottom
                                                       multiplier:1
                                                         constant:0]];

[contentView selfLayoutIfNeeded];

DLog(@"contentView: %@", contentView);

[view addSubview:contentView];

[view addConstraint:[NSLayoutConstraint constraintWithItem:contentView
                                                 attribute:NSLayoutAttributeCenterX
                                                 relatedBy:view
                                                    toItem:NSLayoutRelationEqual
                                                 attribute:NSLayoutAttributeCenterX
                                                multiplier:1
                                                  constant:0]];

[view addConstraint:[NSLayoutConstraint constraintWithItem:contentView
                                                 attribute:NSLayoutAttributeCenterY
                                                 relatedBy:view
                                                    toItem:NSLayoutRelationEqual
                                                 attribute:NSLayoutAttributeCenterY
                                                multiplier:1
                                                  constant:0]];

日志:

DEBUG | -[LoginViewController createConfigurePanel] | contentView: <UIView: 0x17e997d0; frame = (-21 -34; 42 68); layer = <CALayer: 0x17e9e4d0>>

contentView中有2个按钮和2个标签。我添加了按钮和标签。然后我将contentView的右侧属性设置为a按钮的右侧属性,并将contentView的bottom属性设置为done标签的右侧属性,因为我知道这将是视图中的最低项。这有助于为contentView提供内在大小。

因此,contentView将变得包含其子视图所需的大小。

我认为这不会影响内容视图的中心化,但在这一点上,我还没有找到为什么中心无法工作的线索。

编辑2:

我不认为描述或追踪提供了任何有趣的内容:

(lldb) po [[UIWindow keyWindow] recursiveDescription]
<UIWindow: 0x17d947f0; frame = (0 0; 768 1024); autoresize = W+H; gestureRecognizers = <NSArray: 0x17d96070>; layer = <UIWindowLayer: 0x17d95770>>
   | <UIView: 0x17eca770; frame = (0 0; 768 1024); transform = [0, 1, -1, 0, 0, 0]; autoresize = W+H; tag = 444; layer = <CALayer: 0x17ecae70>>
   |    | <UIView: 0x17d96cb0; frame = (20 20; 100 180); clipsToBounds = YES; layer = <CALayer: 0x17dd0220>>
   |    |    | <UIView: 0x17d72a00; frame = (-21 -51; 42 102); clipsToBounds = YES; layer = <CALayer: 0x17dd0340>>
   |    |    |    | <GradientButton: 0x17d74b60; baseClass = UIButton; frame = (0 0; 42 29); clipsToBounds = YES; opaque = NO; layer = <CALayer: 0x17dd09d0>>
   |    |    |    |    | <UIImageView: 0x17eb9a30; frame = (0 0; 42 29); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x17ec9510>>
   |    |    |    | <UILabel: 0x17ee7970; frame = (5 29; 32 17); text = 'Sync'; clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x17ee7900>>
   |    |    |    | <GradientButton: 0x17ee7d30; baseClass = UIButton; frame = (0 56; 42 29); clipsToBounds = YES; opaque = NO; layer = <CALayer: 0x17ee7e40>>
   |    |    |    |    | <UIImageView: 0x17ebdb90; frame = (0 0; 42 29); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x17ed0cd0>>
   |    |    |    | <UILabel: 0x17ee96f0; frame = (5 85; 32 17); text = 'Sync'; clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x17ee9680>>

(lldb) po [[UIWindow keyWindow] _autolayoutTrace]

*<UIWindow:0x17d947f0>
|   *<UIView:0x17eca770>
|   |   *<UIView:0x17d96cb0>
|   |   |   *<UIView:0x17d72a00>
|   |   |   |   *<GradientButton:0x17d74b60>
|   |   |   |   |   <UIImageView:0x17eb9a30>
|   |   |   |   *<UILabel:0x17ee7970>
|   |   |   |   *<GradientButton:0x17ee7d30>
|   |   |   |   |   <UIImageView:0x17ebdb90>
|   |   |   |   *<UILabel:0x17ee96f0>

1 个答案:

答案 0 :(得分:0)

在构建视图后的某个点放置一个断点,并根据视图和布局调试正在设置的内容。使用以下两个debug命令来显示实际情况:

po [[UIWindow keyWindow] recursiveDescription]
po [[UIWindow keyWindow] _autolayoutTrace]

如果您无法自行了解这些信息,如果您将结果添加到原始问题中,我们仍然可以派上用场,这样我们就可以更深入地了解问题。