基于子视图为父视图设置高度约束

Set up height constraint for superview based on child views

如何为父视图设置高度约束,其中父视图的高度是其子视图的总高度,子视图可以是多行 UILabel 的集合(高度可以根据字体大小或如何改变)显示了多行文本)。

您可以通过将第一个标签的顶部约束到自己的顶部,然后将最后一个标签的底部约束到自己的底部来实现。中间的每个标签的顶部都限制在前一个标签的底部。

@interface SomeView: UIView
@end

@implementation SomeView

- (instancetype)init {
    self = [super init];
    if (!self)
        return nil;

    // create an array of random labels
    NSArray <UILabel*> *labels = [self labelsWithRandomText:10];

    // add each label to the view, setting it's top to the previous view's bottom
    UIView *previousView = self;
    for (UILabel *label in labels) {
        [self addSubview:label];

        // bound the left and right of the label to match the parent view
        [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[label]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(label)]];

        // if this is the first label being added, set its top to self's top
        // otherwise set its top to the bottom of the previous view
        NSLayoutAttribute previousAttribute = previousView == self ? NSLayoutAttributeTop : NSLayoutAttributeBottom;
        [self addConstraint:[NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:previousView attribute:previousAttribute multiplier:1 constant:0]];

        // update previous view
        previousView = label;
    }

    // constrain self's bottom to the bottom of the last label
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:previousView attribute:NSLayoutAttributeBottom multiplier:1 constant:0]];

    return self;
}

// create an array of labels w/ random color and background text
- (NSArray <UILabel *> *)labelsWithRandomText:(int)labelCount {
    NSMutableArray <UILabel*> *labels = [NSMutableArray new];
    for (int i = 0; i < labelCount; i++) {
        UILabel *label = [UILabel new];
        label.translatesAutoresizingMaskIntoConstraints = NO;
        label.numberOfLines = 0;
        label.backgroundColor = [self randomColor];
        label.text = [self randomString];
        [labels addObject:label];
    }

    return labels;
}

// create random color
- (UIColor *)randomColor {
    return [UIColor colorWithRed:(arc4random()%255)/255. green:(arc4random()%255)/255. blue:(arc4random()%255)/255. alpha:1];
}

// create random string
- (NSString *)randomString {
    static NSArray <NSString*> *words;
    static NSInteger wordCount;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        words = @[@"cat ", @"dog ", @"bird ", @"went ", @"home ", @"with ", @"under ", @"red ", @"blue ", @"green "];
        wordCount = [words count];
    });

    NSMutableString *randomString = [NSMutableString new];

    // create somewhere between 10-30 words
    int randomWordCount = arc4random() % 20 + 10;
    for (int i = 0; i < randomWordCount; i++) {
        [randomString appendString:words[arc4random() % wordCount]];
    }
    return randomString;
}

@end