Adding programatically created views into scrollview vertically (Linear layout in iOS)

ε祈祈猫儿з 提交于 2019-12-08 15:16:30

In case of using AutoLayout in the context of a UIScrollView I would recommend using a ContentView insider your UIScrollView. Just add them to the ViewControllers View inside the viewDidLoad function.

@interface YourViewController ()
@property (nonatomic, strong) UIScrollView *dataScrollView;
@property (nonatomic, strong) UIView* contentView;
@end

@implementation YourViewController
@synthesize dataScrollView, contentView;

- (void) viewDidLoad {
    [super viewDidLoad];

    dataScrollView  = [[UIScrollView alloc] init];
    contentView = [[UIView alloc] init];

    // adding the Views programmatically to the hierarchy
    [self.view addSubview:dataScrollView];
    [dataScrollView addSubview:contentView];

    // don't translate the AutoresizingMask into constraints
    dataScrollView.translatesAutoresizingMaskIntoConstraints  = NO;
    contentView.translatesAutoresizingMaskIntoConstraints = NO;

    // backgroundColor as you wish?
    dataScrollView.backgroundColor = [UIColor clearColor];
    contentView.backgroundColor = [UIColor clearColor];

    [dataScrollView setScrollEnabled:YES];
    [dataScrollView setAlwaysBounceVertical:YES];

    NSDictionary* viewsDictionary = NSDictionaryOfVariableBindings(dataScrollView, contentView);
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[dataScrollView]|" options:0 metrics: 0 views:viewsDictionary]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[dataScrollView]|" options:0 metrics: 0 views:viewsDictionary]];
    [dataScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[contentView(==dataScrollView)]|" options:0 metrics: 0 views:viewsDictionary]];
    [dataScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[contentView]|" options:0 metrics: 0 views:viewsDictionary]];

    // see below
    // [self setUpViews];
}

This Code will do the Trick for one single view. Add your required Views as Subview to the contentView and set the Constraints.

- (void) setUpViews {
    UILabel* testLabel = [[UILabel alloc] init];
    [testLabel setText:@"Lorem Ipsum"];
    testLabel.translatesAutoresizingMaskIntoConstraints = NO;
    [contentView addSubview: testLabel];

    // clean up your code with this metrics Dictionary
    NSDictionary *metrics = @{@"margintop": @40,
                          @"marginleft": @10,
                          @"marginright": @10,
                          @"marginbottom": @20}

    // the Views we want to layout with Constraints
    NSDictionary *viewsDictionary = @{
                                  @"contentView":contentView,
                                  @"dataScrollView":dataScrollView,
                                  @"testLabel": testLabel}

    // Horizontal (testlabel)
    [contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-marginleft-[testLabel]-marginright-|" options:0 metrics: metrics views:viewsDictionary]];
    // Vertical
    [contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-margintop-[testLabel]-marginbottom-|" options:0 metrics: metrics views:viewsDictionary]];
}

Referring to your question of adding multiple Views in a for-loop, there are a lot of possible ways. This could be the easiest solution with constraintsWithVisualFormat.

- (void) setUpViews {
    NSDictionary *metrics = @{@"margintop": @40,
                          @"marginleft": @10,
                          @"marginright": @10,
                          @"marginbottom": @20,
                          };
    // Alsways like to have contentView and DataScrollView here
    NSMutableDictionary* dictViews = [[NSMutableDictionary alloc] initWithDictionary:@{@"contentView":contentView,
                                                                                   @"dataScrollView":dataScrollView}];

    // Basic Leading-String for Vertical Constraints
    NSString* verticalConstraintsString = @"V:|-margintop-";
    for (NSUInteger index = 0; index < 10; index++) {
        // Do your Magic here & add your View
        UILabel* testLabel = [[UILabel alloc] init];
        [testLabel setText:@"Lorem Ipsum"];
        testLabel.translatesAutoresizingMaskIntoConstraints = NO;
        [contentView addSubview: testLabel];

        // Add to global Mutable Views-Dictionary dictViews
        [dictViews setObject:testLabel forKey:[NSString stringWithFormat:@"testLabel%lu", (unsigned long)index]];
        // add "[testlabel1]" to the vertical Constraints
        verticalConstraintsString = [NSString stringWithFormat:@"%@[testLabel%lu]-", verticalConstraintsString, (unsigned long)index];
        // Add Horizontal Constraints
        [contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"H:|-marginleft-[testLabel%lu]-marginright-|", (unsigned long)index] options:0 metrics: metrics views:@{@"testLabel-%lu":testLabel}]];
    }

    // Trailing-String
    verticalConstraintsString = [NSString stringWithFormat:@"%@marginbottom-|", verticalConstraintsString];
    NSDictionary *viewsDictionary = [[NSDictionary alloc] initWithDictionary:dictViews];

    // finally adding the vertical Constraints
    [contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:verticalConstraintsString options:0 metrics: metrics views:viewsDictionary]];
}

I hope this will help you to get your Views right.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!