2015-08-04 8 views
1

У меня возникают проблемы с UIScrollView с использованием ограничений автоматической компоновки. У меня есть следующий вид иерархии, с ограничениями, установленными через IB:UIScrollView с автоматическими ограничениями компоновки: автоматический подсчет размера контента

- 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**) 

enter image description here

Я хочу простой список scrollabel кнопок. Вот мой код:

- (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! Но есть ограничения как для верхней, так и для нижней части. Это должно быть так:

enter image description here

Но с моим кодом это так. Любая помощь будет отличной.

enter image description here

ответ

0

Я нашел решение я искал 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! 
0

Поскольку вы используете ограничения автоматической компоновки на contentView, его высота (рама) будет равна нулю в методе viewDidLoad. Вы должны переместить свой код в метод viewDidLayoutSubviews и попытаться добавить туда свои кнопки.

Вы должны получить высоту содержимого. Пожалуйста, дайте мне знать, если это сработает. Надеюсь это поможет.

Смотрите этот вопрос для справки: iOS AutoLayout - get frame size width

+0

Я не пытаюсь получить доступ к высоте в любом месте. Я просто добавил взгляды и ограничения и ожидаю правильного поведения от scrollview и contentview. – Mbt925

1

Вы можете добавить ограничение на вид контейнера для прокрутки представления как о равной высоте & одинаковой ширина. Также, когда вы добавляете ограничение на кнопки, не забывайте добавлять нижние ограничения к кнопкам, так как это решит конец прокрутки (размер содержимого).

+0

Я использую автомат. Поэтому размер содержимого scrollview должен рассчитываться автоматически. – Mbt925

+1

Вы можете добавить ограничение в представление контейнера для просмотра прокрутки в виде равной высоты и равной ширины. он будет работать ... –

0

Я не думаю, что мы не можем добавить Автокомпоновки непосредственно к ContainerView внутри ScrollView с Характеристической Размер как по умолчанию, так что я добавить ContainerView, как подвид программно:

- (void)viewDidLoad{ 
    [super viewDidLoad]; 

    self.contentView = [[UIView alloc] initWithFrame:CGRectZero]; 
    [self.scrollView addSubview:self.contentView]; 

    //Then add your button here as normal. 
    //... 
} 

И Гертеж Сингх прав, мы необходимо обновить кадр в 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 ....; 
} 

Я просто хочу помочь, чтобы не было хорошим решением, но это работает для меня.

+0

Спасибо за решения, но я искал более динамичный способ, и я нашел его здесь: http://www.apeth.com/iOSBook/ch20.html – Mbt925

Смежные вопросы