iOS scrollView自動布局技巧之二 - 純代碼自動布局

scrollView 純代碼自動布局

目錄:

  • scrollView 自動布局分析
  • demo 源碼分享

  1. 使用 scrollView 可以分為兩種情況

    • ① scrollView 的子控件有著固定的bounds侨艾;

    • ② scrollView 的子控件都使用自動布局動態(tài)設(shè)置約束匀奏,其大小尺寸會隨數(shù)據(jù)變化。

注意:
- 不管以上那種情況页响,scrollView 本身的大小和位置一定要相對固定!
- 可以使用frame直接設(shè)置颤霎,也可以使用自動布局設(shè)置呈宇。

  1. 設(shè)置 scrollView 的滾動范圍,也可以分為兩種情況
    • 直接設(shè)置 scrollView 的 contentSize
      (這種方式就是直接固定設(shè)置 scrollView 的可滾動范圍)
    • 利用 scrollView 的子控件撐起來
      (撐起來多大即彪,可滾動范圍就有多大)

根據(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 變化 + 子控件撐起來

首先來做個分析:

  1. scrollView不管怎么使用纷宇,一般來說都必須要固定尺寸(大小和位置)
    • 直接設(shè)置frame
    • 使用自動布局設(shè)置
  2. 當(dāng)子控件比較多并且每個視圖比較小夸盟,布局起來就比較麻煩,此時(shí)布局技巧
  3. 子控件撐起來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為豎直、水平方向皆可滾動着饥,注意觀察滾動條位置犀农。

scrollView01.png

圖1

scrollView02.png

圖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è)置布局是不是很方便呢朝巫?

-- end
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市石景,隨后出現(xiàn)的幾起案子劈猿,更是在濱河造成了極大的恐慌拙吉,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件揪荣,死亡現(xiàn)場離奇詭異筷黔,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)仗颈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門佛舱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人揽乱,你說我怎么就攤上這事名眉。” “怎么了凰棉?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵损拢,是天一觀的道長。 經(jīng)常有香客問我撒犀,道長福压,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任或舞,我火速辦了婚禮荆姆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘映凳。我一直安慰自己俱饿,他們只是感情好暇咆,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布齿兔。 她就那樣靜靜地躺著云矫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪矫渔。 梳的紋絲不亂的頭發(fā)上彤蔽,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機(jī)與錄音庙洼,去河邊找鬼顿痪。 笑死,一個胖子當(dāng)著我的面吹牛油够,可吹牛的內(nèi)容都是我干的蚁袭。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼叠聋,長吁一口氣:“原來是場噩夢啊……” “哼撕阎!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起碌补,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤虏束,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后厦章,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體镇匀,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年袜啃,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了汗侵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡群发,死狀恐怖晰韵,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情熟妓,我是刑警寧澤雪猪,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站起愈,受9級特大地震影響只恨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜抬虽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一官觅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧阐污,春花似錦休涤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至隘膘,卻和暖如春疑故,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背弯菊。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工纵势, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人管钳。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓钦铁,卻偏偏與公主長得像,于是被迫代替她去往敵國和親才漆。 傳聞我的和親對象是個殘疾皇子牛曹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容