在具有自动布局的UIScrollview中以编程方式使用UIStackView

时间:2019-07-02 14:26:48

标签: ios scrollview uistackview

我总是使用tableView在小屏幕设备中实现垂直滚动。  对我来说,通过编程方式创建可滚动视图非常困难。

我的代码在下面。

 -(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 个答案:

答案 0 :(得分:1)

使滚动视图与自动布局一起使用的关键是确保您具有垂直约束和元素高度以及水平约束和元素宽度的完整“链”。

以下是我想想的一个示例(您看到的绿色“ 8点水平线”是scrollView背景色,因为出现了{{{1 }} <?xml version="1.0" encoding="UTF-8"?> <commandes xmlns:od="http://www.w3.org/2001/XMLSchema-instance"> <order id="1" lines="1"> <orderline id="1" quantity="2" item="Thing 1"/> </order> <order id="2" lines="2"> <orderline id="2" quantity="1" item="Thing 3"/> <orderline id="3" quantity="1" item="Thing 2"/> </order> <order id="3" lines="1"> <orderline id="4" quantity="3" item="Other"/> </order> </commandes> 8-pt之间的垂直约束:

enter image description here

enter image description here

“底部”灰色视图的高度限制为topView,因此我们可以向上滚动:

enter image description here

以下是创建该代码的代码:

bottomView

注意:我发现将相关任务组合在一起非常容易-尤其是在设计/调试布局期间。因此,在该代码中,您将看到以下分组:

  • 视图实例化
  • 查看属性设置
  • 500-pts操作
  • 约束设置

编辑: 进行了一些更改,以反映textView至少要 个点200的要求高度(使用-(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], ] ]; } 约束)。