關于 UISCrollView 的 contentSize 計算的兩種方法谤饭。

在 App 開發(fā)中,基本上只要能滑動的 UI 都是 scrollView懊纳。

有時候感覺揉抵,蘋果這點做的非常不友好。為什么搞的這么麻煩嗤疯?
在其他的比如 HTML 中冤今,滑動無非就是超過了某個容器的可視范圍,于是就給了一個滑動條身弊。
很自然的一件事情辟汰。
到了蘋果這不光需要自己去注意這點。在使用純的 UISCrollView 的時候阱佛,我們還需要自己去手動計算可以滾動動的范圍帖汞。

吐槽歸吐槽,但 UIScrollView 的 contentSize 還是需要去計算的凑术。


情況一

我們知道 UIScrollView 里面每一個子元素的大小以及子元素的個數(shù)翩蘸。
比如:新特性界面

    UIScrollView *sv = [[UIScrollView alloc] init];
    sv.contentSize = CGSizeMake(圖片數(shù)量 * 圖片的寬, 圖片的高);

這種情況也非常簡單,數(shù)字和大小都是確定的淮逊。只需要帶入計算即可催首。


情況二

每一個子視圖的高度固定扶踊,但是子視圖的個數(shù)不確定。

在這里有就兩種做法了郎任。

第一種秧耗,申明一個 height 屬性,每次添加一個視圖的時候舶治,都根據(jù)前視圖的高度 & 邊距信息來記錄累加高度分井。
最后設置成 scrollView 的 contentSize.

 UIScrollView *sv1 = [[UIScrollView alloc] init];
    
    CGFloat height2 = 0;
    
    UIView *c1 = [UIView new];
    [sv1 addSubview:c1];
    sv1.top = 20;
    sv1.height = 300;
    
    height2 += 300;
    
    UIView *c2 = [UIView new];
    c2.top = 40;
    c2.height = 700;
    
    height += 740;
    
    // .........
    
    sv1.contentSize = CGSizeMake(self.view.bounds.size.width, height2);

第二種情況,利用約束霉猛。

  • 在 scrollView 中添加一個內(nèi)容容器 containerView尺锚。只設置約束 left ,top ,width。
  • 然后再這個 containerView 中惜浅,添加各種子視圖瘫辩,并設置子視圖的位置和大小約束。
  • 第一個子視圖必須設置 top 約束坛悉。
  • 最后一個子視圖伐厌,必須設置一個 bottom 約束,用來計算 containerView 的 height 屬性吹散。
  • 當約束計算完畢之后弧械,containerView 的 大小和位置就確定好了八酒。就可以間接的利用它來設置 scrollView 的 contentSize 了空民。
 UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:scrollView];
    scrollView.showsHorizontalScrollIndicator = NO;
    scrollView.alwaysBounceVertical = YES;
    scrollView.backgroundColor = [UIColor whiteColor];
    // 先不設置 contentSize.畢竟子視圖有多長還不知道
    //scrollView.contentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, xxxx);
    
    /**
     
        不把 scrollView 的 contentSize 寫死,.
        而是在其內(nèi)部放一個uiview.
        在 uiview 內(nèi)部添加子視圖,用約束設置.
        根據(jù)內(nèi)部約束的子視圖計算 uiview 的大小.
        然后根據(jù) uiview 的大小設置 scrollView 的 contentSize.
     */
    
    /**
        現(xiàn)在的做法:
        記錄每一個子視圖的高度記憶邊距數(shù)據(jù),然后累加起來.
     */
    UIView *containerView = [[UIView alloc] init];
    // 容器,只設置 x,y,w  高度 h 先不設置,用子視圖的約束去計算
    [scrollView addSubview:containerView];
    [containerView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.top.offset(0);
        make.width.equalTo(scrollView.mas_width);
    }];
    
    
    UIView *childView1 = [[UIView alloc] init];
    [containerView addSubview:childView1];
    childView1.backgroundColor = [UIColor blueColor];
    
    [childView1 mas_makeConstraints:^(MASConstraintMaker *make) {
        // 頭部約束
        make.top.offset(20);
        make.left.offset(0);
        make.width.equalTo(containerView.mas_width);
        make.height.offset(300);
        
    }];
    
    UIView *childView2 = [[UIView alloc] init];
    [containerView addSubview:childView2];
    childView2.backgroundColor = [UIColor greenColor];
    
    [childView2 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.offset(0);
        make.top.equalTo(childView1.mas_bottom).offset(50);
        make.height.offset(400);
        make.width.equalTo(containerView.mas_width);
        
    }];

    
    UIView *childView3 = [[UIView alloc] init];
    [containerView addSubview:childView3];
    childView3.backgroundColor = [UIColor greenColor];
    
    [childView3 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.offset(0);
        make.top.equalTo(childView2.mas_bottom).offset(100);
        make.width.equalTo(containerView.mas_width);
        make.height.offset(700);
        
        // 底部約束,用于計算containerView 的 height
       make.bottom.offset(-50);
    }];

    // 不用去調(diào)用約束立即計算的代碼,有個小技巧,使用 dispatch_after 即可拿到約束計算完畢之后的 containerView 的height 值.
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"%.f",containerView.height);
        scrollView.contentSize = CGSizeMake(self.view.width, containerView.height);
    });


效果如下:

利用約束計算 scrollView 的 contentSize.gif

一個問題?
為什么要在 scrollView 中添加一個 containerView? 而不是直接往 scrollView 中直接添加子視圖羞迷?

因為 scrollView 本身的大小已經(jīng)確定了界轩。它不具備擴展和延伸性。
能夠延伸的是它內(nèi)部的 contentSize 尺寸下的子視圖衔瓮。
如果把 子視圖直接添加到 scrollView 浊猾,并添加約束,那么大小范圍热鞍,之后 scrollView 的 frame 那么大葫慎。
且子視圖可能會重疊在一起,甚至會出現(xiàn)約束沖突薇宠。

但是如果偷办,在scrollView 內(nèi)部添加一個 containerView 那么,它的大小就可以不確定了澄港。只用約束設置 left top width 椒涯。高度則是由其內(nèi)部的第一個子視圖的 top 約束以及最后一個子視圖的 bottom 約束計算得出即可。

最后在使用 dispatch_after 小技巧回梧,不需要提前計算約束废岂,就可以把 containerView 的 height 賦值給 scrollView 的 contentSize祖搓。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市湖苞,隨后出現(xiàn)的幾起案子拯欧,更是在濱河造成了極大的恐慌,老刑警劉巖财骨,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件哈扮,死亡現(xiàn)場離奇詭異,居然都是意外死亡蚓再,警方通過查閱死者的電腦和手機滑肉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來摘仅,“玉大人靶庙,你說我怎么就攤上這事⊥奘簦” “怎么了六荒?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長矾端。 經(jīng)常有香客問我掏击,道長,這世上最難降的妖魔是什么秩铆? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任砚亭,我火速辦了婚禮,結果婚禮上殴玛,老公的妹妹穿的比我還像新娘捅膘。我一直安慰自己,他們只是感情好滚粟,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布寻仗。 她就那樣靜靜地躺著,像睡著了一般凡壤。 火紅的嫁衣襯著肌膚如雪署尤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天亚侠,我揣著相機與錄音曹体,去河邊找鬼。 笑死盖奈,一個胖子當著我的面吹牛混坞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼究孕,長吁一口氣:“原來是場噩夢啊……” “哼啥酱!你這毒婦竟也來了?” 一聲冷哼從身側響起厨诸,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤镶殷,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后微酬,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绘趋,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年颗管,在試婚紗的時候發(fā)現(xiàn)自己被綠了陷遮。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡垦江,死狀恐怖帽馋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情比吭,我是刑警寧澤绽族,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站衩藤,受9級特大地震影響吧慢,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜赏表,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一检诗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧底哗,春花似錦岁诉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽哗蜈。三九已至前标,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間距潘,已是汗流浹背炼列。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留音比,地道東北人俭尖。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親稽犁。 傳聞我的和親對象是個殘疾皇子焰望,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355

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