1. 程式人生 > >ScrollView自動佈局

ScrollView自動佈局

前言

相信很多同學都遇到這麼一個問題:在storyboard上如何使用scrollview自動根據內容的增長而自動使其contentSize而變化,以使之可滾動。或者如何使用純程式碼實現scrollview上使新增的控制元件在超出顯示螢幕時可滾動,也就是根據內容自動計算出其contentSize的問題。

在這裡,將使用storyboardMasonry純程式碼實現scrollview自動佈局。如果有說得不正確的地方,歡迎指出!

說明:本人向來不使用xib或者storyboard開發,幾乎都是使用純程式碼的autolayout,也就是使用Masonry。不管是使用Swift開發或者是Objective-C

開發,都會基於MasonrySnapKit寫一套控制元件,以簡化開發。

ScrollView Autolayout

我們實現下面的效果圖:

image

第一步:新增UIScrollView並佈局約束為點滿整個self.view

點選右下角的第二個小圖示,新增約束如下圖:

image

設定UIScrollView的上、下、左、右與self.view的上、下、左、右都一致,相當於點滿了整個self.view

注意:Constraints to margin儘量不要勾選,也就是是否使用margin的意思。如果學習過HTML,應該更容易理解。在HTML中有margin、padding,對於一個盒(Box),除了content外,還有padding、margin。其中padding是與內容的間隔,而margin是與外部的間隔。在這裡,如果勾選了,就會相差8個畫素。個人在使用中都會去掉這個勾選。

第二步:新增紅色的標籤(redLabel)

首先設定這個標籤的相關前景色、背景色、numberOfLines=0,新增文字等,然後選中這個標籤,像上面第一步中的圖片指示,點選右下角小圖示,在彈出框中新增約束。

新增約束為:左、上、右與self.view的左、上、右相等,內容會自動換行,高度會自動得到。這裡可以使左、上與UIScrollView的左、上相等,但是不能使用右(trailing)不能等於UIScrollView的右(trailing)。

注意:在使用佈局子控制元件到UIScrollView上時,由於UIScrollView的right是不確定的,因為UIScrollView

contentSize,即內容的寬和內容的高。

第三步:新增綠色標籤(blueLabel)

與第二步差不多,新增前景色等,新增約束為:使blueLabel的leading和width分別等於redLabel的leading和width,再使blueLabel的top等於redLabel的bottom再加上20(間隔)。

第四步:新增圖片(imgView)

新增圖片很簡單,設定約束為:width和height值都設定為250,top為blueLabel的bottom再加上20,然後設定水平居中就可以了。看下圖:

image

第五步:新增白色標籤(whiteLabel)

與第三步差不多,只是top為imgView的bottom再加上20就可以了。

第六步:新增紅色按鈕

按鈕顏色等配置就不說了,只說如何新增約束。這裡需要注意一點,需要設定bottom,以確定scrollview的contentSize.height。新增約束為:leading、trailing、bottom分別與scrollview的leading、trailing、bottom+20相等,再設定其height、top就可以了。這裡使button的bottom=scrollview.bottom,也就可以確定scrollview的contentSize.height了.

平分佈局

下面我們來實現下面的佈局,使控制元件平分顯示。

image

第一行:如何平分這兩個控制元件使其等寬、等高、間隔20,與self.view的左、右間隔10畫素。

  • 首先,同時選中這兩個控制元件,先新增下面的約束:設定這兩個控制元件Equal widths,Equal heights。
  • 設定左邊的控制元件的約束為:leading為10,height為80,trailing為右邊控制元件的leading-20,top為0.
  • 設定右邊的控制元件的約束為:trailing為-10,top=左邊控制元件的top就可以實現了。

注意:這裡設定左邊的控制元件的trailing為右邊控制元件的leading,再減去20個畫素(間隔),這樣才能確定其寬。

第二行:如何三等分顯示,使中間兩個間隔都為20,外邊兩個與邊界的間隔都為10

  • 首先,同時選中這三個控制元件,新增約束:等寬、等高。
  • 設定button3的top距離上方控制元件的底部20畫素,再設定button4、button5的top都與button3的top一致。設定button3的leading為10,trailing為button4的leading-20.
  • 設定button4的trailing為button5的leading-20
  • 設定button5的trailing為-10

第三行:如何將兩個控制元件的高度等分

第三行中左邊是一個圖片,右邊是兩個按鈕,一上一下且等寬等高,中間間隔10畫素。

  • 首先,固定左邊的圖片,設定約束:寬、高都為250,leading為10,top為20.
  • 將button6和button7設定為等寬、等高
  • 設定button6的leading為10,trailing為-10,top為左邊圖片的top
  • 設定button7的leading和trailing都為button6的leading和trailing
  • 最後,同時選中button6和button7,按住ctrl,拖向左邊的圖片,設定AspectRadio,設定其比例為40:100,這樣每個按鈕的高度就是圖片的高度的40%。當然這裡我們也可以直接設定button7的bottom=左邊的圖片的bottom,這樣也可以達到目的。

基於Masonry的Autolayout

下面我們給self.view上放一個點滿的scrollview:

UIScrollView *scrollView = [[UIScrollView alloc] init];
[self.view addSubview:scrollView];

然後,我們放一個說明標籤,具體說明看程式碼註釋:

// 放一個說明標籤
UILabel *tipLabel = [[UILabel alloc] init];
tipLabel.backgroundColor = [UIColor redColor];
tipLabel.numberOfLines = 0;
tipLabel.textColor = [UIColor whiteColor];
tipLabel.textAlignment = NSTextAlignmentLeft;
[scrollView addSubview:tipLabel];
[tipLabel mas_makeConstraints:^(MASConstraintMaker *make) {
  make.left.top.mas_equalTo(10);
  // 注意:這裡直接使用weakSelf.view,相當於weakSelf.view.mas_right
  // 另外:由於要與weakSelf.view.mas_right距離10畫素,因此這裡值為-10。
  make.right.mas_equalTo(weakSelf.view).offset(-10);
}];
tipLabel.text = @"這個標籤是使用Masonry完成的純程式碼自動佈局。這個標籤的約束新增方式為:使左、上與父檢視的左、上分別相等,使右邊與self.view的右邊的相距-10,就可以確定其寬。這裡不能使用使右等於scrollview的右,因為scrollview是可以滾動的,其右是不確定的。";

接下來,在tipLabel下面又放一個標籤,具體說明看程式碼註釋:

UILabel *codeLabel = [[UILabel alloc] init];
codeLabel.backgroundColor = [UIColor redColor];
codeLabel.numberOfLines = 0;
codeLabel.textColor = [UIColor whiteColor];
codeLabel.textAlignment = NSTextAlignmentLeft;
[scrollView addSubview:codeLabel];
[codeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
  // 使與tipLabel的左、右分別對齊 ,也就確定了寬
  make.left.right.mas_equalTo(tipLabel);

  make.top.mas_equalTo(tipLabel.mas_bottom).offset(40);
  // 注意:這裡直接使用weakSelf.view,相當於weakSelf.view.mas_right
  // 另外:由於要與weakSelf.view.mas_right距離10畫素,因此這裡值為-10。
}];
codeLabel.text = @"本標籤的約束新增方式為:使左、右與上面的標籤的左、右分別對齊,由此就可確定左、右和寬,再使頂部top等於上面的標籤的bottom再加上40個畫素。\n歡迎掃一掃我的微信公眾號二維碼,關注公眾號,或者直接搜尋iOSDevShares。若想加QQ群,請加:324400294";

下面我們在上面的標籤之下,放一個圖片。對於圖片,如果圖片本身大小是正好合適的,那麼我們可以使用sizeToFit方法來生成適應,但是我們圖片過大或者過小,那麼我們可以在約束中指定為固定的大小:

UIImageView *codeImageView = [[UIImageView alloc] init];
codeImageView.image = [UIImage imageNamed:@"微信公眾號.jpg"];
[scrollView addSubview:codeImageView];
[codeImageView mas_makeConstraints:^(MASConstraintMaker *make) {
  make.centerX.equalTo(weakSelf.view);
  make.top.mas_equalTo(codeLabel.mas_bottom).offset(20);
  make.size.mas_equalTo(CGSizeMake(250, 250));
}];

// 由於圖片過大,需要限制。如果是圖片剛好,可以不設定大小的約束,使用下面的方式。
//  [codeImageView sizeToFit];

使用程式碼又是如何平分控制元件的呢?下面看看這兩個標籤,其內容是可變的,不知道哪個的內容多,但是其寬是一樣的,只是高度會隨內容而動態變化。

// 平分兩個控制元件
UILabel *avgLabel1 = [[UILabel alloc] init];
avgLabel1.backgroundColor = [UIColor redColor];
avgLabel1.numberOfLines = 0;
avgLabel1.textColor = [UIColor whiteColor];
avgLabel1.textAlignment = NSTextAlignmentCenter;
[scrollView addSubview:avgLabel1];
avgLabel1.text = @"本控制元件的約束新增方式為:使left與父檢視的left相距10畫素,使top=上面的圖片的bottom再加40畫素,使right=右邊這個標籤的left再減去20個畫素(間隔),使height=80。";

UILabel *avgLabel2 = [[UILabel alloc] init];
avgLabel2.backgroundColor = [UIColor redColor];
avgLabel2.numberOfLines = 0;
avgLabel2.textColor = [UIColor whiteColor];
avgLabel2.textAlignment = NSTextAlignmentCenter;
[scrollView addSubview:avgLabel2];
avgLabel2.text = @"本控制元件的約束新增方式為:使right=self.view的right再減去10畫素,然後再設定寬、top都與左右的檢視一樣,就可以實現水平平分了。本控制元件的約束新增方式為:使right=self.view的right再減去10畫素,然後再設定寬、top都與左右的檢視一樣,就可以實現水平平分了。";

[avgLabel1 mas_makeConstraints:^(MASConstraintMaker *make) {
  make.left.mas_equalTo(10);
  make.top.mas_equalTo(codeImageView.mas_bottom).offset(40);
  make.right.mas_equalTo(avgLabel2.mas_left).offset(-20);
}];
[avgLabel2 mas_makeConstraints:^(MASConstraintMaker *make) {
  make.right.mas_equalTo(weakSelf.view.mas_right).offset(-10);
  make.width.top.mas_equalTo(avgLabel1);
}]

最後,看看我們是如何使scrollview隨內容而變化,也就是可以滾動。另外,上面的兩個控制元件是等寬的,但是其高都是不定的,到底以哪個的bottom作為scrollView的bottom呢?這裡使用了很巧妙的方法。

// 使用edges使點滿整個self.view
[scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
  make.edges.equalTo(weakSelf.view);

  // 如果這兩個標籤的內容都是不確定的,也就是不確定哪個的內容更多,那麼可以這麼設定。
  // 這樣就可以保證使用內容最多的標籤作為scrollview的contentSize參考。
  // 用於確定scrollview的contentSize.height
  make.bottom.mas_greaterThanOrEqualTo(avgLabel1.mas_bottom).offset(40);
  make.bottom.mas_greaterThanOrEqualTo(avgLabel2.mas_bottom).offset(40);
}];

原始碼

公眾號搜尋「iOS開發技術分享」快速關注微訊號:iOSDevShares QQ群:324400294

image

相關推薦

ScrollView自動佈局的實現方式

背景 開發中,可能會有一些頁面顯示的元素很多,可能會超出一個螢幕,但也不適合用 TableView 或者 CollectionView,此時我們一般會用 ScrollView,那麼就會出現自動佈局的問題。 實現方式 純程式碼 特點 編碼繁

ScrollView自動佈局技巧

scrollView自動佈局技巧 步驟: 1. sb中拖scrollView 2. 設定scrollView上下左右為0 4. 拖一個UIView"yellowView"到scrollView中

[開發細節]scrollview自動佈局contentsize設定

在自動佈局中,一個待顯示的檢視新增到scrollview,並設定邊界為scrollview的四個邊。你會發現僅僅這樣還不夠,這時候待顯示檢視根本沒有顯示。 查找了相關資料後發現要額外設定待顯示容器的寬高,確定了待顯示容器的寬高後再設定靠近scrollview的四個邊。 /

ScrollView自動佈局

前言 相信很多同學都遇到這麼一個問題:在storyboard上如何使用scrollview自動根據內容的增長而自動使其contentSize而變化,以使之可滾動。或者如何使用純程式碼實現scrollview上使新增的控制元件在超出顯示螢幕時可滾動,也就是根

scrollView的contentSize,contentOffset,contentInsets以及xib自動佈局

scrollView三個屬性含義解釋 http://www.xuebuyuan.com/693438.html,首先參考這個網址的介紹,contentSize和contentOffset就不多說了,理解起來比較簡單,關鍵在於後面這個contentInsets,

利用ScrollView實現佈局自動滾動

首先1,獲得ScrollView sc = (ScrollView) findViewById(R.id.scroll);//scroll物件      LinearLayout mlayout = (LinearLayout) findViewById(R.id.mlayo

YYLabel 自動佈局 不換行 numberOfLines無效

最近是用Masonry自動佈局YYLabel的時候,發現設定了label.numberOfLines = 0,2,3;這些東西之後,label還是沒有換行。 搞了一下子發現,YYLabel還得設定一個preferredMaxLayoutWidth屬性,這個屬性是設定最大寬度,設定完才能有換行

【UGUI】自動佈局

UGUI自動佈局一直適應 GridLayoutGroup,但是,使用grid時有一個很嚴重的問題就是:當開啟Profiler中的Deep Profile時,整個Unity都會崩潰.(目前使用版本v5.6.0)此外,還有一個問題,但是我給忘了... 所以,還是自己動手造輪子吧,程式碼如下: using Uni

iOS仿QQ側滑選單、登入按鈕動畫、仿鬥魚直播APP、城市選擇器、自動佈局等原始碼

iOS精選原始碼 QQ側滑選單,右滑選單,QQ展開選單,QQ好友分組 image 登入按鈕 image 3分鐘快捷建立高效能輪播圖 ScrollView巢狀ScrolloView(UITableView 、UICollectionView)解決方案

iOS頭條新聞App、自動佈局、省市區聯動、登入按鈕動畫、Alert彈框效果等原始碼

iOS精選原始碼 LEEAlert -- 優雅的Alert ActionSheet 登入按鈕 省市區三級聯動 JHViewCorner - 一行程式碼搞定圓角 JHFrameLayout - 一行程式碼實現自動佈局 MVVM+Masonry+UI

iOS Xib自動佈局(轉)

使用Xib可以實現控制元件的螢幕適配,但是並不是十全十美。因為我們使用Xib新增約束的時候,比如說距離左邊多少距離,這是設定的一個確定的阿拉伯數字,是絕對的,並不是設定的一個比例,在不同的機型上面,裝置的尺寸寬高不一定,Xib以絕對的阿拉伯數字新增約束並不能做到完美的螢幕適配

關於Autolayout和Masonry自動佈局的幾個坑

自動佈局 02 Mar 2016Comments 前言 最近遇到一個複雜檢視:根控制器裡面有上下兩個子控制器,子控制器中各自實現類似PageView的檢視,然後PageView的每一頁是一個WebView,同時中間有個可拖拽的控制元件,實現上下兩個控制器檢視的大小調整。採用子

ios ——SDAutolayout自動佈局下的cell自定義

想要實現 這種樣式的cell ,即與邊界有一定距離, 然後又需要cell的高度可以根據標題自適應,所以選擇了sdautolayout自動佈局框架。 生成一個繼承自UITableViewCell的類,首先定義一個白色的背景bgview,然後依次定義四個label,糧給U

【OC梳理】自動佈局

自動佈局基礎篇 關於自動佈局的基本使用,參考網上的文章即可,如: iOS開發-自動佈局篇:史上最牛的自動佈局教學! 自動佈局進階篇 抗拉伸與抗壓縮 相信許多比較少使用自動佈局的同學對下面的引數都感覺比較頭疼: 其實不難,請往下看: #####Content Hugging Prio

Auto Layout Process 自動佈局過程

與使用springs and struts(autoresizingMask)比較,Auto layout在view顯示之前,多引入了兩個步驟:updating constraints 和laying out views。每一個步驟都依賴於上一個。display依賴lay

iOS 自動佈局框架

目前iOS開發中大多數頁面都已經開始使用Interface Builder的方式進行UI開發了,但是在一些變化比較複雜的頁面,還是需要通過程式碼來進行UI開發的。而且有很多比較老的專案,本身就還在採用純程式碼的方式進行開發。 而現在iPhone和iPad螢幕尺寸越來越多,雖然開

IOS UIScrollView的自動佈局

寫在開始的話:如果感覺博文解決了你的問題,想轉載本文,請尊重勞動成果,註明轉載來源,謝謝! 這兩天剛研究完成IOS的自動佈局,然後想在UIScrollView裡面也設定自動佈局,完成上下滑動。剛開始感覺UIScrollView的自動佈局也跟其他的一樣簡單,但只有經過嘗試才知

自動佈局中的NSAutoresizingMaskLayoutConstraint

在使用自動佈局的時候,如果是自己通過程式碼直接寫的約束(即不通過SnapKit等第三方庫或StoryBoard,Xib之類),那麼就會出現NSAutoresizingMaskLayoutConstrai

ScrollView佈局填滿整個螢幕

ScrollView直接子View只能有一個,一般高度是自適應內容高度,可能會遇到不能填滿整個螢幕的情況,那麼解決辦法就是增加一個屬性:  android:fillViewport="true"  程式碼: <pre name="code" class="java"&

ios自動佈局的坑和與之有關的特殊坑

前行文 autoLayout自動佈局在ios開發中有其不可比擬的優勢,簡化的程式碼,讓後期維護變得更簡單。這裡不做autoLayout與autoResize的優勢分析,但是在開發過程中如果不注意就會遇到autoLayout意想不到的坑,下面稍微總結一下,