Программное использование UIStackView в UIScrollview с Autolayout - PullRequest
0 голосов
/ 02 июля 2019

Я всегда использую tableView для реализации вертикальной прокрутки на устройствах с маленьким экраном.Мне сложно создать прокручиваемый вид с помощью programmatic.

Мой код указан ниже.

 -(void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    UIView *bottomView = [[UIView alloc] init];
    UIView *topView = [[UIView alloc] init];

    UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
    scrollView.bounces = false;

    [self.view addSubview:scrollView];
    [scrollView addSubview:topView];
    [scrollView addSubview:bottomView];

    bottomView.translatesAutoresizingMaskIntoConstraints  = false;
    topView.translatesAutoresizingMaskIntoConstraints  = false;

    bottomView.backgroundColor = [UIColor lightGrayColor];
    topView.backgroundColor = [UIColor redColor];
    self.view.backgroundColor = [UIColor yellowColor];

    [topView.leftAnchor constraintEqualToAnchor:scrollView.leftAnchor constant:0].active = YES;
    [topView.topAnchor constraintEqualToAnchor:scrollView.bottomAnchor constant:0].active = YES;
    [topView.widthAnchor constraintEqualToAnchor:scrollView.widthAnchor].active = YES;

    UITextView *textView = [[UITextView alloc] init];
    textView.translatesAutoresizingMaskIntoConstraints = false;
    [topView addSubview:textView];

    [textView.topAnchor constraintEqualToAnchor:topView.topAnchor constant:100].active = YES;
    [textView.widthAnchor constraintEqualToAnchor:topView.widthAnchor].active = YES;
    [textView.leftAnchor constraintEqualToAnchor:topView.leftAnchor].active = YES;
    [textView.heightAnchor constraintEqualToConstant:200].active = YES;


    UILabel *label = [[UILabel alloc] init];
    label.font = [UIFont systemFontOfSize:20];
    label.numberOfLines = 0;
    label.translatesAutoresizingMaskIntoConstraints = false;

    [topView addSubview:label];

    label.text = @"more than one line /r more than one line /r more than one line /r ";

    UIStackView *stackView = [[UIStackView alloc] init];

    [topView addSubview:stackView];
    stackView.translatesAutoresizingMaskIntoConstraints = false;

    [stackView.topAnchor constraintEqualToAnchor:textView.bottomAnchor constant:20].active = YES;
    [stackView.widthAnchor constraintEqualToAnchor:topView.widthAnchor constant:-40].active = YES;
    [stackView.leftAnchor constraintEqualToAnchor:topView.leftAnchor constant:20].active = YES;


    int number1 = arc4random_uniform(3) + 2;

    for (int i = 0; i < number1; i++){

        [stackView addArrangedSubview:label];
    }


    UIStackView *stackView2 = [[UIStackView alloc] init];
    [topView addSubview:stackView2];
    stackView2.translatesAutoresizingMaskIntoConstraints = false;
    [stackView2.topAnchor constraintEqualToAnchor:stackView.bottomAnchor constant:20].active = YES;
    [stackView2.widthAnchor constraintEqualToAnchor:topView.widthAnchor constant:-40].active = YES;
    [stackView2.leftAnchor constraintEqualToAnchor:topView.leftAnchor constant:20].active = YES;

    int number2 = arc4random_uniform(7) + 2;

    for (int i = 0; i < number2; i++){

        [stackView2 addArrangedSubview:label];
    }


    stackView.axis = UILayoutConstraintAxisVertical;
    stackView2.axis = UILayoutConstraintAxisVertical;

    stackView.spacing = 5;
    stackView.distribution = UIStackViewDistributionEqualSpacing;
    stackView2.spacing = 5;
    stackView2.distribution = UIStackViewDistributionEqualSpacing;

    [topView.bottomAnchor constraintEqualToAnchor:stackView2.bottomAnchor].active = YES;

    [bottomView.leftAnchor constraintEqualToAnchor:scrollView.leftAnchor constant:0].active = YES;
    [bottomView.topAnchor constraintEqualToAnchor:topView.bottomAnchor constant:0].active = YES;
    [bottomView.heightAnchor constraintEqualToConstant:1000.0].active = YES;
    [bottomView.widthAnchor constraintEqualToAnchor:scrollView.widthAnchor].active = YES;



}

Как установить scrollView.contentSize.height равным bottomView.maxY?

Какустановить scrollView.contentSize.width равным self.view.frame.size.width?

Когда я буду вводить в textView все больше и больше, высота textView соответственно улучшится?

=====================

Из-за моего кода не понятно.Я рисую эскиз.

enter image description here

1 Ответ

1 голос
/ 02 июля 2019

Ключом к тому, чтобы заставить представления прокрутки работать с автоматическим макетом, является обеспечение полной «цепочки» вертикальных ограничений и высот элементов, а также горизонтальных ограничений и ширины элементов.

Вот примерто, о чем я думаю вы собираетесь (зеленая "8-пунктовая горизонтальная линия", которую вы видите, это цвет фона scrollView, который вы видите, потому что между topView и 8-pt имеется вертикальное ограничениеbottomView):

enter image description here

enter image description here

«Нижний» серый вид имеет высотуограничение 500-pts, поэтому мы можем прокрутить вверх:

enter image description here

Вот код для создания этого:

-(void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    UIScrollView *scrollView = [UIScrollView new];
    UIView *topView = [UIView new];
    UIView *bottomView = [UIView new];
    UITextView *textView = [UITextView new];
    UIStackView *stackView1 = [UIStackView new];
    UIStackView *stackView2 = [UIStackView new];

    scrollView.backgroundColor = [UIColor greenColor];
    topView.backgroundColor = [UIColor redColor];
    bottomView.backgroundColor = [UIColor lightGrayColor];
    self.view.backgroundColor = [UIColor yellowColor];

    scrollView.translatesAutoresizingMaskIntoConstraints = false;
    topView.translatesAutoresizingMaskIntoConstraints  = false;
    bottomView.translatesAutoresizingMaskIntoConstraints  = false;
    textView.translatesAutoresizingMaskIntoConstraints = false;
    stackView1.translatesAutoresizingMaskIntoConstraints = false;
    stackView2.translatesAutoresizingMaskIntoConstraints = false;

    // don't bounce the scroll view
    scrollView.bounces = false;

    // we want the textView to auto-size its height, so set it to non-scrolling
    textView.scrollEnabled = NO;

    // slightly bigger than default font
    textView.font = [UIFont systemFontOfSize:18.0];

    // stackView properties
    stackView1.axis = UILayoutConstraintAxisVertical;
    stackView2.axis = UILayoutConstraintAxisVertical;

    stackView1.spacing = 5;
    stackView1.distribution = UIStackViewDistributionFill;
    stackView2.spacing = 5;
    stackView2.distribution = UIStackViewDistributionFill;

    // add the scrollView to the view
    [self.view addSubview:scrollView];

    // constrain scroll view to all 4 sides
    [NSLayoutConstraint activateConstraints:
     @[
       [scrollView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
       [scrollView.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor],
       [scrollView.leadingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leadingAnchor],
       [scrollView.trailingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.trailingAnchor]
       ]
     ];

    // add textView and both stack views to topView
    [topView addSubview:textView];
    [topView addSubview:stackView1];
    [topView addSubview:stackView2];

    // setup constraints for topView's subviews
    [NSLayoutConstraint activateConstraints:
     @[

       // textView top, leading and trailing to topView with 8-pts "padding"
       [textView.topAnchor constraintEqualToAnchor:topView.topAnchor constant:8.0],
       [textView.leadingAnchor constraintEqualToAnchor:topView.leadingAnchor constant:8.0],
       [textView.trailingAnchor constraintEqualToAnchor:topView.trailingAnchor constant:-8.0],

       // textView should be *at least* 200-pts tall, getting taller if enough text is added
       [textView.heightAnchor constraintGreaterThanOrEqualToConstant:200.0],

       // stackView1 top to text view bottom, leading and trailing to topView with 8-pts "padding"
       [stackView1.topAnchor constraintEqualToAnchor:textView.bottomAnchor constant:8.0],
       [stackView1.leadingAnchor constraintEqualToAnchor:topView.leadingAnchor constant:8.0],
       [stackView1.trailingAnchor constraintEqualToAnchor:topView.trailingAnchor constant:-8.0],

       // stackView2 top to stackView1 bottom, leading and trailing to topView with 8-pts "padding"
       [stackView2.topAnchor constraintEqualToAnchor:stackView1.bottomAnchor constant:8.0],
       [stackView2.leadingAnchor constraintEqualToAnchor:topView.leadingAnchor constant:8.0],
       [stackView2.trailingAnchor constraintEqualToAnchor:topView.trailingAnchor constant:-8.0],

       // and constrain stackView2 to bottom of topView with 8-pts padding
       [stackView2.bottomAnchor constraintEqualToAnchor:topView.bottomAnchor constant:-8.0],

       ]

     ];

    // now let's add some labels to the stack views
    int numLabels = arc4random_uniform(3) + 2;

    for (int i = 0; i < numLabels; i++){

        UILabel *label = [UILabel new];
        label.font = [UIFont systemFontOfSize:20];
        label.numberOfLines = 0;
        label.translatesAutoresizingMaskIntoConstraints = false;
        label.backgroundColor = [UIColor cyanColor];

        label.text = [NSString stringWithFormat:@"Label %d\nIn stackView 1 \nwith more than one line", i];

        [stackView1 addArrangedSubview:label];

    }

    numLabels = arc4random_uniform(3) + 2;

    for (int i = 0; i < numLabels; i++){

        UILabel *label = [UILabel new];
        label.font = [UIFont systemFontOfSize:20];
        label.numberOfLines = 0;
        label.translatesAutoresizingMaskIntoConstraints = false;
        label.backgroundColor = [UIColor colorWithRed:1.0 green:0.75 blue:0.5 alpha:1.0];   // light-orange

        label.text = [NSString stringWithFormat:@"Label %d\nIn stackView 2 \nwith more than one line", i];

        [stackView2 addArrangedSubview:label];

    }

    // add topView and bottomView to the scrollView
    [scrollView addSubview:topView];
    [scrollView addSubview:bottomView];

    // setup topView and bottomView's constraints
    [NSLayoutConstraint activateConstraints:
     @[

       // topView top, leading, trailing and width to scrollView
       [topView.topAnchor constraintEqualToAnchor:scrollView.topAnchor constant:0.0],
       [topView.leadingAnchor constraintEqualToAnchor:scrollView.leadingAnchor constant:0.0],
       [topView.trailingAnchor constraintEqualToAnchor:scrollView.trailingAnchor constant:0.0],
       [topView.widthAnchor constraintEqualToAnchor:scrollView.widthAnchor constant:0.0],

       // bottomView top to topView bottom (8-pts padding), leading, trailing, width to scrollView
       [bottomView.topAnchor constraintEqualToAnchor:topView.bottomAnchor constant:8.0],
       [bottomView.leadingAnchor constraintEqualToAnchor:scrollView.leadingAnchor constant:0.0],
       [bottomView.trailingAnchor constraintEqualToAnchor:scrollView.trailingAnchor constant:0.0],
       [bottomView.widthAnchor constraintEqualToAnchor:scrollView.widthAnchor constant:0.0],

       // and bottom of bottomView to bottom of scrollView
       [bottomView.bottomAnchor constraintEqualToAnchor:scrollView.bottomAnchor constant:0.0],

       // bottomView has no subviews to provide a height, so constrain it to 500-pts tall
       [bottomView.heightAnchor constraintEqualToConstant:500.0],

       ]

     ];


}

Примечание: мне гораздо легче - особенно во время макетов проектирования / отладки - группировать связанные задачи вместе.Итак, в этом коде вы увидите группировки для:

  • просмотра экземпляров
  • просмотра настроек свойств
  • addSubview() действий
  • ограничениянастройки

Редактировать: пара изменений, сделанных, чтобы отразить требование, чтобы textView было как минимум 200-поддержки высоты (с использованием ограничения greaterThanOrEqualTo).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...