使用nsautolayout在他们的超级视图的中心创建一组uiview

时间:2014-08-03 02:42:48

标签: nsautolayout

我想在红色区域的中心制作一些uiview。 我怎么能用NSAutolayout做到这一点?即使用户轮换?

横向模式

....................................

       - view -              ... 200px margin from right
           | gap
       - view -
           | gap
       - view -
           | gap
       - view -

....................................

1 个答案:

答案 0 :(得分:0)

你的问题不是很清楚。

您可以创建约束以使视图相对于给定方向的另一个视图居中。例如,您可以将一个视图的“centerX”属性设置为等于其他视图的centerX。 (您也可以使其与其他视图的前导,尾随,左侧或右侧边缘相同。或者甚至其他不具有直观意义的属性,如宽度,顶部等,如果这是您想要的。)

如果您尝试将图组中的视图堆栈垂直居中,则有几种方法。首先,您可以将该组嵌入到另一个紧密围绕它的视图中。它的顶部将等于堆栈中第一个视图的顶部,其底部将等于堆栈中最后一个视图的底部。然后,您可以设置约束以使该容器视图在其超级视图中居中。

另一种方法是创建隐藏的间隔视图。将一个视图(顶部间隔符)放在堆栈中第一个视图的上方。使其顶部等于超级视图的顶部。使其底部等于堆栈中第一个视图的顶部。同样,在底部设置一个垫片。它的顶部将等于堆栈中最后一个视图的底部。它的底部等于超视图的底部。然后,在顶部垫片和底部垫片之间设置约束以使它们的高度相等。这确保了堆栈和superview之间的空间在顶部和底部是相同的。

如果需要,同样的技术也适用于水平方向。


更新

这里有一些我根本没有测试过的代码:

UIView* redArea = /* ... */;
NSArray* stackViews = /* ... */;

UIView* container = [[UIView alloc] initWithFrame:NSZeroRect];

[redArea addSubview:container];

UIView* previousView = nil;
for (UIView* view in stackViews)
{
    [container addSubview:view];
    if (previousView)
    {
        // Make a gap between the stacked views
        NSDictionary* views = NSDictionaryOfVariableBindings(view, previousView);
        NSArray* constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[previousView]-[view]" options:0 metrics:nil views:views];
        [container addConstaints:constraints];
    }
    else
    {
        // Make the top of the container the same as the top of the first stacked view
        NSDictionary* views = NSDictionaryOfVariableBindings(view);
        NSArray* constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view]" options:0 metrics:nil views:views];
        [container addConstaints:constraints];
    }

    // Make sure the container is at least as wide as each stacked view
    NSDictionary* views = NSDictionaryOfVariableBindings(view);
    NSArray* constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(>=0)-[view]-(>=0)-|" options:0 metrics:nil views:views];
    [container addConstaints:constraints];

    previousView = view;
}

if (previousView)
{
    // Make the bottom of the container the same as the bottom of the last stacked view
    NSDictionary* views = NSDictionaryOfVariableBindings(previousView);
    NSArray* constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[previousView]|" options:0 metrics:nil views:views];
    [container addConstaints:constraints];
}

// Make the container as narrow as possible after satisfying other constraints
NSLayoutConstraint* minimalWidth = [NSLayoutConstraint constraintWithItem:container attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:0];
minimalWidth.priority = UILayoutPriorityFittingSizeLevel - 1;
[container addConstraint:minimalWidth];

// Center the container within the red area
NSLayoutConstraint* centerVertically = [NSLayoutConstraint constraintWithItem:container attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:redArea attribute:NSLayoutAttributeCenterY multiplier:1 constant:0];
NSLayoutConstraint* centerHorizontally = [NSLayoutConstraint constraintWithItem:container attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:redArea attribute:NSLayoutAttributeCenterX multiplier:1 constant:0];
[redArea addConstraints:@[centerVertically, centerHorizontally]];

这将更容易在IB中设置。