【问题标题】:Adding programatically created views into scrollview vertically (Linear layout in iOS)将编程创建的视图垂直添加到滚动视图中(iOS 中的线性布局)
【发布时间】:2015-07-02 20:52:10
【问题描述】:

我想将编程创建的 UIView 添加到具有自动布局约束的滚动视图中。就像 Android 中的垂直线性布局。 (在目标 c 中不迅速)

我在情节提要的视图控制器内有滚动视图。所以基本上我想在垂直布局中创建和添加几个视图,在该滚动视图中没有空格。我想根据视图高度动态设置滚动视图的容器大小。

每个视图内部都有标签,每个视图需要根据文本大小动态设置其高度。但可能我需要稍后再谈。

for (int i=0; i<10; i++)
{
    UIView *viewOne = UIView.new;
    [viewOne setTranslatesAutoresizingMaskIntoConstraints:NO];
    viewOne.backgroundColor = [UIColor redColor];
    NSDictionary *viewsDictionary = @{@"viewOne" : viewOne};
    NSDictionary *metricsDictionary = @{@"horizontalSpacing" : @10};

    [self.scrollview addSubview:viewOne];

    NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-horizontalSpacing-[viewOne]-horizontalSpacing-|"
                                                                             options:NSLayoutFormatDirectionLeadingToTrailing
                                                                             metrics:metricsDictionary
                                                                               views:viewsDictionary];

    NSArray *const_Height = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[viewOne(50)]"
                                                                    options:0
                                                                    metrics:nil
                                                                      views:viewsDictionary];

    [viewOne addConstraints:const_Height];
    [self.scrollview addConstraints:horizontalConstraints];
}

使用该代码我可以添加视图,但我需要在另一个下添加一个。

【问题讨论】:

    标签: ios objective-c autolayout constraints


    【解决方案1】:

    如果在 UIScrollView 的上下文中使用 AutoLayout,我建议在 UIScrollView 内部使用 ContentView。只需将它们添加到 viewDidLoad 函数内的 ViewControllers 视图中。

    @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];
    }
    

    此代码将为一个视图完成诀窍。将所需的视图作为子视图添加到 contentView 并设置约束。

    - (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]];
    }
    

    参考您在for循环中添加多个视图的问题,有很多可能的方法。这可能是 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]];
    }
    

    我希望这将帮助您正确地查看。

    【讨论】:

    • 感谢您的回答,这对您有很大帮助。但我也想在循环中创建这些视图。那么如何相互设置约束呢?在您的示例中,我如何在循环中创建 testLabel。使用此代码,它将在旧的顶部添加每个 testLabel。因为它们都对顶部布局有相同的约束。
    • 我已经更新了我的答案并试图解决你的问题。
    • 谢谢它解决了我的问题。我将 testLabel-%lu 更改为 testLabel%lu。像魅力一样工作:)
    • 你应该也给出了设置滚动视图内容大小的解决方案
    • @MithunR。我不确定我是否误解了您的评论,但 UIScrollViews 的 contentSize 属性应该与此解决方案无关。滚动视图内容的大小由我的“contentView”对象的大小自动定义。 “contentView”对象的大小再次由它包含视图的大小设置。请纠正我对此的想法:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-17
    • 1970-01-01
    • 2016-02-29
    • 2019-03-03
    相关资源
    最近更新 更多