【问题标题】:UIScrollView with Auto Layout Constraints: Auto Content Size Calculation具有自动布局约束的 UIScrollView:自动内容大小计算
【发布时间】:2015-08-04 20:45:27
【问题描述】:

我在使用自动布局约束时遇到了 UIScrollView 的问题。我有以下视图层次结构,通过 IB 设置约束:

- ScrollView (leading, trailing, bottom and top spaces to Superview)
-- ContainerView (leading, trailing, bottom and top spaces to ScrollView)
--- Button 1 (full width, **top space to ContainerView**)
--- Button 2 (full width, below Button 1)
--- Button n (full width, below Button n-1, **bottom space to ContainerView**)

我想要一个简单的滚动标签按钮列表。这是我的代码:

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self.view setBackgroundColor:[UIColor redColor]];
    [self.contentView setBackgroundColor:[UIColor yellowColor]];

    UIView *lastView= self.contentView; // use for top constraint

    NSInteger topBottomMargin= 10, leftRightMargin= 16;
    for (int i=0; i<10; i++) {
        UIButton *button= [UIButton buttonWithType:UIButtonTypeSystem];
        button.translatesAutoresizingMaskIntoConstraints= NO;
        [button setTitle:[NSString stringWithFormat:@"Button %d", i] forState:UIControlStateNormal];

        [self.contentView addSubview:button];

        // add constraints
        // top
        [self.contentView addConstraint:[NSLayoutConstraint
                                         constraintWithItem:lastView
                                         attribute:NSLayoutAttributeBottom
                                         relatedBy:NSLayoutRelationGreaterThanOrEqual
                                         toItem:button
                                         attribute:NSLayoutAttributeTop
                                         multiplier:1.0 constant:-topBottomMargin]];
        // left
        [self.contentView addConstraint:[NSLayoutConstraint
                                         constraintWithItem:self.contentView
                                         attribute:NSLayoutAttributeLeading
                                         relatedBy:NSLayoutRelationEqual
                                         toItem:button
                                         attribute:NSLayoutAttributeLeading
                                         multiplier:1.0 constant:-leftRightMargin]];
        // right
        [self.contentView addConstraint:[NSLayoutConstraint
                                         constraintWithItem:self.contentView
                                         attribute:NSLayoutAttributeTrailing
                                         relatedBy:NSLayoutRelationEqual
                                         toItem:button
                                         attribute:NSLayoutAttributeTrailing
                                         multiplier:1.0 constant:leftRightMargin]];

        lastView= button;
    }
    // bottom
    [self.contentView addConstraint:[NSLayoutConstraint
                                     constraintWithItem:self.contentView
                                     attribute:NSLayoutAttributeBottom
                                     relatedBy:NSLayoutRelationEqual
                                     toItem:lastView
                                     attribute:NSLayoutAttributeBottom
                                     multiplier:1.0 constant:topBottomMargin]];    
}

好像contentView的高度是0!但是它的顶部和底部都有限制。应该是这样的:

但我的代码是这样的。任何帮助都会很棒。

【问题讨论】:

    标签: ios objective-c uiscrollview autolayout ios-autolayout


    【解决方案1】:

    您可以将约束添加到容器视图以滚动视图为等高和等宽。此外,当您向按钮添加约束时,不要忘记向按钮添加底部约束,因为它将决定滚动视图的结束(内容大小)。

    【讨论】:

    • 我正在使用自动布局。所以scrollview的内容大小应该是自动计算出来的。
    • 您可以将约束添加到容器视图以滚动视图为等高和等宽。它会工作......
    【解决方案2】:

    由于您在 contentView 上使用了自动布局约束,因此在 viewDidLoad 方法中它的高度(帧)将为零。您应该将您的代码移动到viewDidLayoutSubviews 方法中并尝试在那里添加您的按钮。

    你应该在那里得到 contentView 的高度。请让我知道这是否有效。希望这会有所帮助。

    请参阅此问题以供参考:iOS AutoLayout - get frame size width

    【讨论】:

    • 我不想在任何地方访问高度。我刚刚添加了视图和约束,并期望滚动视图和内容视图的正确行为。
    【解决方案3】:

    我认为我们不能将自动布局直接添加到 ScrollView 内的 ContainerView 中,并将 Intrinsic Size 作为默认值,所以我以编程方式将 ContainerView 添加为子视图:

    - (void)viewDidLoad{
        [super viewDidLoad];
    
        self.contentView = [[UIView alloc] initWithFrame:CGRectZero];
        [self.scrollView addSubview:self.contentView];
    
        //Then add your button here as normal.
        //...
    }
    

    而 Gurtej Singh 是对的,我们必须更新 viewDidLayoutSubviews 中的框架:

    - (void)viewDidLayoutSubviews
     {
         [super viewDidLayoutSubviews];
        //Don't for get to update your self.scrollView.contentSize if you want to able to scroll
        //...
    
        //Update your contentView frame based on scrollview frame and self.scrollView.contentSize.
         self.contentView.frame = self.scrollView.bounds or ....;
     }
    

    我只是想帮忙,这可能不是一个好的解决方案,但它对我有用。

    【讨论】:

    【解决方案4】:

    我找到了我正在寻找的解决方案here

    [super viewDidLoad];
    UIScrollView* sv = [UIScrollView new];
    sv.backgroundColor = [UIColor whiteColor];
    sv.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:sv];
    [self.view addConstraints:
     [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[sv]|"
                                             options:0 metrics:nil
                                               views:@{@"sv":sv}]];
    [self.view addConstraints:
     [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[sv]|"
                                             options:0 metrics:nil
                                               views:@{@"sv":sv}]];
    UILabel* previousLab = nil;
    for (int i=0; i<30; i++) {
        UILabel* lab = [UILabel new];
        lab.translatesAutoresizingMaskIntoConstraints = NO;
        lab.text = [NSString stringWithFormat:@"This is label %i", i+1];
        [sv addSubview:lab];
        [sv addConstraints:
         [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(10)-[lab]"
                                                 options:0 metrics:nil
                                                   views:@{@"lab":lab}]];
        if (!previousLab) { // first one, pin to top
            [sv addConstraints:
             [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(10)-[lab]"
                                                     options:0 metrics:nil
                                                       views:@{@"lab":lab}]];
        } else { // all others, pin to previous
            [sv addConstraints:
             [NSLayoutConstraint
              constraintsWithVisualFormat:@"V:[prev]-(10)-[lab]"
                                      options:0 metrics:nil
                                        views:@{@"lab":lab, @"prev":previousLab}]];
        }
        previousLab = lab;
    }
    // last one, pin to bottom and right, this dictates content size height
    [sv addConstraints:
     [NSLayoutConstraint constraintsWithVisualFormat:@"V:[lab]-(10)-|"
                                             options:0 metrics:nil
                                               views:@{@"lab":previousLab}]];
    [sv addConstraints:
     [NSLayoutConstraint constraintsWithVisualFormat:@"H:[lab]-(10)-|"
                                             options:0 metrics:nil
                                               views:@{@"lab":previousLab}]];
    // look, Ma, no contentSize!
    

    【讨论】:

      猜你喜欢
      • 2022-06-17
      • 1970-01-01
      • 1970-01-01
      • 2014-04-08
      • 1970-01-01
      • 2012-11-10
      • 1970-01-01
      相关资源
      最近更新 更多