scrollView 純代碼自動布局
目錄:
- scrollView 自動布局分析
- demo 源碼分享
-
使用 scrollView 可以分為兩種情況
① scrollView 的子控件有著固定的bounds侨艾;
② scrollView 的子控件都使用自動布局動態(tài)設(shè)置約束匀奏,其大小尺寸會隨數(shù)據(jù)變化。
注意:
- 不管以上那種情況页响,scrollView 本身的大小和位置一定要相對固定!
- 可以使用frame直接設(shè)置颤霎,也可以使用自動布局設(shè)置呈宇。
- 設(shè)置 scrollView 的滾動范圍,也可以分為兩種情況
- 直接設(shè)置 scrollView 的 contentSize
(這種方式就是直接固定設(shè)置 scrollView 的可滾動范圍) - 利用 scrollView 的子控件撐起來
(撐起來多大即彪,可滾動范圍就有多大)
- 直接設(shè)置 scrollView 的 contentSize
根據(jù)排列組合,共有 2*2 = 4 中情況活尊,下面分別分析:
1.子控件 bounds 固定 + 直接設(shè)置 contentSize
這種情況沒什么好說的隶校,直接設(shè)置即可。
2.子控件 bounds 固定 + 子控件撐起來
這種情況相當(dāng)于是第四種情況的簡化版蛹锰,故請先看[第四種方式]深胳。
3.子控件 bounds 變化 + 直接設(shè)置 contentSize
我們知道,只要設(shè)置 scrollView 的 contentSize铜犬,就限定了 scrollView 的可滾動范圍舞终。所以這種情況,并不能很好的根據(jù)子控件的變化而動態(tài)顯示完整的內(nèi)容癣猾。
所以子控件bounds變化的情況敛劝,需要使用[第四種方式]設(shè)置。
4.子控件 bounds 變化 + 子控件撐起來
首先來做個分析:
- scrollView不管怎么使用纷宇,一般來說都必須要固定尺寸(大小和位置)
- 直接設(shè)置frame
- 使用自動布局設(shè)置
- 當(dāng)子控件比較多并且每個視圖比較小夸盟,布局起來就比較麻煩,此時(shí)布局技巧
- 子控件撐起來scrollView會有兩種情況
- 能撐起來 -> 有滾動范圍
- 撐不起來 -> 無滾動像捶,完整顯示子控件
第1條上陕,兩種設(shè)置方式,自己根據(jù)實(shí)際情況選擇一種即可拓春;
第2條释簿,將所有子視圖塞進(jìn)一個容器視圖中。即先給scrollView添加一個唯一直接子視圖痘儡。
通俗點(diǎn)說就是創(chuàng)建一個sizeView
設(shè)置其大性颉(直接設(shè)置frame或者使用autolayout設(shè)置皆可),然后將其添加到scrollView的子視圖沉删,其他七七八八的所有小子視圖都添加在這個直接子視圖sizeView
中,這個直接子視圖就相當(dāng)于 contentView醉途。
這樣只要設(shè)置這個直接子視圖sizeView
的大小和約束就好了矾瑰。
如果設(shè)置好了這個直接子視圖sizeView
的約束,那么這個直接子視圖sizeView
的范圍就是 scrollView 的滾動范圍嘍隘擎!
第3條殴穴,其實(shí)設(shè)置子視圖布局就2個要點(diǎn):
-
①子視圖的四邊到父視圖的距離
sizeView.edges.equalTo(scrollView)
- 上面的 edges 就是 top、left、bottom采幌、right 四邊的集合劲够,即四邊的簡便寫法,等同于
make.top.left.bottom.right.equalTo(scrollView)
-
②子視圖 sizeView 的 x休傍、y軸尺寸與 scrollView 可滾動方向的關(guān)系
- 如果想要 scrollView 豎直方向可滾動征绎、水平方向固定,那么設(shè)置 sizeView 的 width 與 scrollView 相等磨取,height 被動態(tài)撐起來
如果想要 scrollView 水平方向可滾動人柿、豎直方向固定,那么設(shè)置 sizeView 的 height 與 scrollView 相等忙厌,width 被動態(tài)撐起來
如果想要 scrollView 豎直方向和水平方向皆可滾動凫岖,那么設(shè)置 sizeView 的 width 與 scrollView 相等,height 被動態(tài)撐起來
以上3中情況逢净,
若 sizeView.height > scrollView.height哥放,可豎直滾動
若 sizeView.height < scrollView.height,無滾動爹土,全部顯示
如圖1婶芭、圖2
圖2為豎直、水平方向皆可滾動着饥,注意觀察滾動條位置犀农。
圖1
圖2
圖2為豎直、水平方向皆可滾動宰掉,注意觀察滾動條位置呵哨。
直接上demo的代碼
//
// ViewController.m
// ScrollView純代碼布局技巧
//
#import "ViewController.h"
#import "Masonry.h"
/// 顏色分類
@implementation UIColor (Hex)
+ (instancetype)hex:(uint32_t)hex {
uint8_t r = (hex & 0xFF0000) >> 16;
uint8_t g = (hex & 0x00FF00) >> 8;
uint8_t b = (hex & 0x0000FF);
return [self colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1];
}
@end
/// ViewController 控制器
@interface ViewController ()
@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UIView *topView;
@property (nonatomic, strong) UIView *midView;
@property (nonatomic, strong) UIView *bottomView;
@property (nonatomic, strong) MASConstraint *midView_height_constrait;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
NSLog(@"viewDidLoad...");
[self setupUI];
}
- (void)setupUI {
// self.view.backgroundColor = UIColor.redColor; //做對比用
// nav
UIButton *right = [[UIButton alloc] init];
[right setTitle:@"變化" forState:UIControlStateNormal];
[right setTitleColor:UIColor.systemBlueColor forState:UIControlStateNormal];
[right addTarget:self action:@selector(onRightChangeAction:) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:right];
// scrollView
self.scrollView = UIScrollView.new;
self.scrollView.backgroundColor = [UIColor hex:0xf2f2f2];
self.scrollView.bounces = YES;
[self.view addSubview:self.scrollView];
[self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view).offset(88);
make.left.bottom.right.equalTo(self.view);
}];
//
// sizeView
UIView *sizeView = UIView.new;
[self.scrollView addSubview:sizeView];
[sizeView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self.scrollView); //edges就是top、left轨奄、bottom孟害、right四邊
}];
//上面的 edges 就是top、left挪拟、bottom挨务、right四邊的集合,簡便寫法(等同于 make.top.left.bottom.right...)
// topView
self.topView = UIView.new;
[sizeView addSubview:self.topView];
[self.topView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.right.mas_equalTo(sizeView);
make.height.mas_equalTo(100); //確定高度玉组,撐起來豎直方向
make.width.equalTo(self.scrollView); //確定寬度谎柄,撐起來水平方向
// 這里水平方向上有一個子視圖撐起來,整個sizeView就會被撐起來
}];
self.topView.backgroundColor = [UIColor systemYellowColor];
// midView
self.midView = UIView.new;
[sizeView addSubview:self.midView];
[self.midView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.topView.mas_bottom);
make.left.right.mas_equalTo(sizeView);
self.midView_height_constrait = make.height.mas_equalTo(200);
}];
self.midView.backgroundColor = UIColor.systemRedColor;
// bottomView
self.bottomView = UIView.new;
[sizeView addSubview:self.bottomView];
[self.bottomView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.midView.mas_bottom);
make.left.bottom.right.mas_equalTo(sizeView);
make.height.mas_equalTo(200); //確定高度惯雳,撐起來豎直方向
}];
self.bottomView.backgroundColor = UIColor.systemBlueColor;
}
- (void)updateHeight:(CGFloat)height {
NSLog(@"\nheight = %.2f", height);
[self.midView mas_updateConstraints:^(MASConstraintMaker *make) {
self.midView_height_constrait = make.height.mas_equalTo(height);
}];
}
- (void)onRightChangeAction:(UIBarButtonItem *)sender {
int height = arc4random_uniform(600);
[self updateHeight:(CGFloat)height];
}
@end
如此設(shè)置布局是不是很方便呢朝巫?