Scrollview And Autolayout

Introduction

This technote provides some information regarding Auto Layout support for UIScrollView. Specifically it demonstrates a "mixed" and a "pure" auto layout approach for UIScrollViews.

Back to Top
In Depth Explanation

In general, Auto Layout considers the top, left, bottom, and right edges of a view to be the visible edges. That is, if you pin a view to the left edge of its superview, you’re really pinning it to the minimum x-value of the superview’s bounds. Changing the bounds origin of the superview does not change the position of the view.

The UIScrollView class scrolls its content by changing the origin of its bounds. To make this work with Auto Layout, the top, left, bottom, and right edges within a scroll view now mean the edges of its content view.

The constraints on the subviews of the scroll view must result in a size to fill, which is then interpreted as the content size of the scroll view. (This should not be confused with the intrinsicContentSize method used for Auto Layout.) To size the scroll view’s frame with Auto Layout, constraints must either be explicit regarding the width and height of the scroll view, or the edges of the scroll view must be tied to views outside of its subtree.

Note that you can make a subview of the scroll view appear to float (not scroll) over the other scrolling content by creating constraints between the view and a view outside the scroll view’s subtree, such as the scroll view’s superview.

Here are two examples of how to configure the scroll view, first the mixed approach, and then the pure approach.

Back to Top
Mixed Approach

Position and size your scroll view with constraints external to the scroll view—that is, the translatesAutoresizingMaskIntoConstraints property is set to NO.

Create a plain UIView content view for your scroll view that will be the size you want your content to have. Make it a subview of the scroll view but let it continue to translate the autoresizing mask into constraints:

Listing 1 Mixed Approach Code Listing

- (void)viewDidLoad {
UIView *contentView;
 
contentView = [[UIView alloc] initWithFrame:CGRectMake(0,0,contentWidth,contentHeight)];
 
[scrollView addSubview:contentView];
 
// DON'T change contentView's translatesAutoresizingMaskIntoConstraints,
// which defaults to YES;
 
// Set the content size of the scroll view to match the size of the content view:
[scrollView setContentSize:CGSizeMake(contentWidth,contentHeight)];
 
 /* the rest of your code here... */
 
}

Create the views you want to put inside the content view and configure their constraints so as to position them within the content view.

Alternatively, you can create a view subtree to go in the scroll view, set up your constraints, and call the systemLayoutSizeFittingSize: method (with the UILayoutFittingCompressedSize option) to find the size you want to use for your content view and the contentSize property of the scroll view.

Back to Top
Pure Auto Layout Approach

To use the pure autolayout approach do the following:

Set translatesAutoresizingMaskIntoConstraints to NO on all views involved.
Position and size your scroll view with constraints external to the scroll view.
Use constraints to lay out the subviews within the scroll view, being sure that the constraints tie to all four edges of the scroll view and do not rely on the scroll view to get their size.
A simple example would be a large image view, which has an intrinsic content size derived from the size of the image. In the viewDidLoad method of your view controller, you would include code similar to the code shown in the listing below:

Listing 2 Pure Auto Layout Approach Code Listing


- (void)viewDidLoad {
    UIScrollView *scrollView;
    UIImageView *imageView;
    NSDictionary *viewsDictionary;
 
    // Create the scroll view and the image view.
    scrollView  = [[UIScrollView alloc] init];
    imageView = [[UIImageView alloc] init];
 
    // Add an image to the image view.
    [imageView setImage:[UIImage imageNamed:"MyReallyBigImage"]];
 
    // Add the scroll view to our view.
    [self.view addSubview:scrollView];
 
    // Add the image view to the scroll view.
    [scrollView addSubview:imageView];
 
    // Set the translatesAutoresizingMaskIntoConstraints to NO so that the views autoresizing mask is not translated into auto layout constraints.
    scrollView.translatesAutoresizingMaskIntoConstraints  = NO;
    imageView.translatesAutoresizingMaskIntoConstraints = NO;
 
    // Set the constraints for the scroll view and the image view.
    viewsDictionary = NSDictionaryOfVariableBindings(scrollView, imageView);
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|" options:0 metrics: 0 views:viewsDictionary]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|" options:0 metrics: 0 views:viewsDictionary]];
    [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[imageView]|" options:0 metrics: 0 views:viewsDictionary]];
    [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[imageView]|" options:0 metrics: 0 views:viewsDictionary]];
 
    /* the rest of your code here... */
}

This would give you a scroll view that resized as the view controller’s view resized (such as on device rotation), and the image view would be a scrolling subview. You don’t have to set the content size of the scroll view.

Back to Top

Document Revision History

Date Notes
2014-02-20
Fixed some typographical errors.
2013-05-08
New document that describes how to work with UIScrollView and autolayout.

还可以参考这个官方链接:
https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithScrollViews.html#//apple_ref/doc/uid/TP40010853-CH24-SW1

最后写一个简单的demo给大家

- (void)viewDidLoad {
    [super viewDidLoad];
  
    //方案一:使用一个容器
    UIScrollView *scrollView = [[UIScrollView alloc]init];
    scrollView.backgroundColor = [UIColor orangeColor];
    scrollView.pagingEnabled =YES;
    
    [self.view addSubview:scrollView];
    [scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.and.left.mas_equalTo(60);
        make.right.mas_equalTo(-60);
        make.height.mas_equalTo(100);
    }];
   
    UIView *containerView = [[UIView alloc]init];
    containerView.backgroundColor = [UIColor redColor];
    [scrollView addSubview:containerView];
    
    
    UIView *view1 = [[UIView alloc] init];
    view1.backgroundColor = [UIColor yellowColor];
    [containerView addSubview:view1];
    [view1 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.left.and.bottom.equalTo(containerView);
        make.width.equalTo(scrollView);
    }];
    
    UIView *view2 = [[UIView alloc] init];
    view2.backgroundColor = [UIColor greenColor];
    [containerView addSubview:view2];
    [view2 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.and.bottom.equalTo(containerView);
        make.width.equalTo(scrollView);
        make.left.equalTo(view1.mas_right);
    }];
    [containerView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(scrollView);
        make.right.mas_equalTo(view2.mas_right);
        make.height.equalTo(scrollView);
    }];

    
    //方案二:不适用中间容器,也可以参考苹果官方文档里加了一个imageview,因为imageView和label都是有intrinsic size.
    UIScrollView *scrollView11 = [[UIScrollView alloc]init];
    scrollView11.backgroundColor = [UIColor redColor];
    scrollView11.pagingEnabled =YES;
    
    [self.view addSubview:scrollView11];
    [scrollView11 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(170);
        make.left.mas_equalTo(60);
        make.right.mas_equalTo(-60);
        make.height.mas_equalTo(100);
    }];
    
    
    UIView *view11 = [[UIView alloc] init];
    view11.backgroundColor = [UIColor yellowColor];
    [scrollView11 addSubview:view11];
    [view11 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.left.and.bottom.equalTo(scrollView11);
        make.width.equalTo(scrollView11);
        make.height.equalTo(scrollView11);
    }];
    
    UIView *view22 = [[UIView alloc] init];
    view22.backgroundColor = [UIColor greenColor];
    [scrollView11 addSubview:view22];
    [view22 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.bottom.right.equalTo(scrollView11);
        make.width.equalTo(scrollView11);
        make.height.equalTo(scrollView11);
        make.left.equalTo(view11.mas_right);
    }];
    

}

Working with Self-Sizing Table View Cells

tableView.estimatedRowHeight = 85.0
tableView.rowHeight = UITableViewAutomaticDimension

NOTE
When working with table view cells, you cannot change the layout of the predefined content (for example, the textLabel, detailTextLabel,and imageView
properties).
The following constraints are supported:
Constraints that position your subview relative to the cell’s content view.
Constraints that position your subview relative to the cell’s bounds.
Constraints that position your subview relative to the predefined content.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容