使用autolayout自定義動態高度的cell
關於使用autolayout建立動態cell,網上也有不少的文章,但是裡面的內容都是說的一個問題,簡稱換湯不換藥,都是說的一些UILabel或者UITextView等等一些控制元件顯示的文字內容不同來實現不同的高度。
但是我們平常使用的自定義cell很多都是顯示不同數量的控制元件,來顯示不同的高度,比如微博首頁,餓了麼首頁那些cell,都是下面顯示不同數量的控制元件來顯示不同高度的cell,那麼下面就讓我們一起看看怎麼使用autolayout實現這種自定義cell
關於使用autolayout實現cell動態高度有兩種實現方式
iOS8以後
iOS8以後比較爽:只需要設定下面兩句程式碼就行了
//設定cell的估計高度
self.tableView.estimatedRowHeight = 200;
//iOS以後這句話是預設的,所以可以省略這句話
self.tableView.rowHeight = UITableViewAutomaticDimension;
你可能沒有看到實現代理方法返回cell高度。明確告訴你iOS8以後不需要實現了,系統會自動推斷出cell的高度。
but,iOS7還是需要
下面就是iOS7實現的方式,還是需要實現這個方法,iOS8那兩句程式碼不寫也可以
//如果要支援iOS7這個方法必須實現
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
//其他程式碼
//自動算高度,+1的原因是因為contentView的高度要比cell的高度小1
CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height + 1;
return height;
}
主要就是下面這句程式碼,能自動計算出contentView的高度和寬度
CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height + 1;
上面這兩種方式可以一起存在,既支援ios7也支援iOS8.
開始demo
先來看一下我們最終的效果:
- 有的cell只有一個UITextLabel,並且label會根據內容的多少來改變高度
- 有的cell下面還有一個UIButton,並且cell會根據有沒有button來動態改變高度
實現思路
- 首先自定義一個cell,順便建立一個xib檔案
- 在xib檔案中把所有包含的控制元件全部搞上去,設定好約束
- 如果不需要哪個控制元件顯示就把哪個控制元件的高約束設定為0
- 如果需要顯示哪個控制元件就保證這個控制元件沒有高度約束(應該容易想的到因為是動態高度的cell,所以不能有高度的約束)
- 然後更新約束,顯示cell
在這裡我們使用xib的方式建立自定義cell
如圖:
這裡設定約束有幾個注意點
- 每一個控制元件都只設置上下左右的約束,不設定寬高的約束,有些必須要固定大小的可以設定一下
- 有些控制元件如果不設定寬高xib會報錯的話,就設定佔位符placehoder
- 像一些要消失或者顯示的控制元件,最好設定他與其他顯示的控制元件間距為0
這是我自定義cell的類
在控制器中我們實現資料來源程式碼
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerNib:[UINib nibWithNibName:@"MyTableViewCell" bundle:nil] forCellReuseIdentifier:@"cell"];
self.tableView.allowsSelection = NO;
//胡亂寫的,為了懶省事,大家湊合著看吧
self.tableData = @[@"1\n2\n3\n4\n5\n6", @"123456789012345678901234567890", @"1\n2", @"1\n2\n3", @"123456789012345678901234567890", @"1\n2\n3\n4\n5\n6", @"123456789012345678901234567890", @"1\n2", @"1\n2\n3", @"123456789012345678901234567890", @"1\n2\n3",@"1\n2\n3",@"123456789012345678901234567890", @"1\n2", @"1\n2\n3", @"123456789012345678901234567890", @"1\n2\n3",@"1\n2\n3"@"123456789012345678901234567890", @"1\n2", @"1\n2\n3", @"123456789012345678901234567890", @"1\n2\n3",@"1\n2\n3"@"123456789012345678901234567890", @"1\n2", @"1\n2\n3", @"123456789012345678901234567890", @"1\n2\n3",@"1\n2\n3"@"123456789012345678901234567890", @"1\n2", @"1\n2\n3", @"123456789012345678901234567890", @"1\n2\n3",@"1\n2\n3"@"123456789012345678901234567890", @"1\n2", @"1\n2\n3", @"123456789012345678901234567890", @"1\n2\n3",@"1\n2\n3"];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.tableData.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
cell.text = self.tableData[indexPath.row];
return cell;
}
我們先使用iOS8的方法
接下來就是去自定義cell類(MyTableView.m)中重寫-updateConstraints 方法
-(void)updateConstraints {
//remove Constraints
[self.height uninstall];
//add Constraints
[self.content mas_makeConstraints:^(MASConstraintMaker *make) {
self.height = make.height.equalTo(@60);//any number
}];
if(self.isShowView == NO) {
//change Height Constrains to be 0
[self.content mas_updateConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(@0);
}];
}
else {
//remove Constraints
[self.height uninstall];
}
[super updateConstraints];
}
- 如果不需要顯示就設定高度約束為0
- 如果需要顯示就把高度約束去掉
這個方法超級重要,有些view需要顯示的話,一定要把高度約束去掉,不然cell迴圈使用的話會出問題。
然後就是設定要顯示的text
-(void)setText:(NSString *)text {
_text=text;
self.textView.text = text;
if ([self.text isEqualToString:@"123456789012345678901234567890"]) {
self.isShowView = NO;
self.button.hidden=YES;
self.content.hidden=YES;
self.intextView.hidden=YES;
}else {
self.isShowView = YES;
self.button.hidden=NO;
self.content.hidden=NO;
self.intextView.hidden=NO;
}
}
接下來在Controller檔案中
將cellForRowAtIndexPath方法改為下面樣子
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
cell.text = self.tableData[indexPath.row];
//返回cell之前重新重新整理約束,重新計算高度
[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
return cell;
}
然後在-viewDidLoad方法中增加兩句話就行了
self.tableView.estimatedRowHeight = 200;
self.tableView.rowHeight = UITableViewAutomaticDimension;
接下來是支援iOS7的
只需要重寫程式碼方法heightForRowAtIndexPath
將這個方法內容改為下面這樣:
//如果要支援iOS7這個方法必須實現
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
self.cell = (MyTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"cell"];
MyTableViewCell *cell = self.cell;
cell.text = [self.tableData objectAtIndex:indexPath.row];
//這句程式碼必須要有,也就是說必須要設定contentView的寬度約束。
//設定以後,contentView裡面的內容才知道什麼時候該換行了
CGFloat contentViewWidth = CGRectGetWidth(self.tableView.frame);
[cell.contentView mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(@(contentViewWidth));
}];
//重新載入約束,每次計算之前一定要重新確認一下約束
[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
//自動算高度,+1的原因是因為contentView的高度要比cell的高度小1
CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height + 1;
return height;
}
好了大概就是這樣吧,具體demo點這裡
相關推薦
使用autolayout自定義動態高度的cell
關於使用autolayout建立動態cell,網上也有不少的文章,但是裡面的內容都是說的一個問題,簡稱換湯不換藥,都是說的一些UILabel或者UITextView等等一些控制元件顯示的文字內容不同來實現不同的高度。 但是我們平常使用的自定義cell很多都是顯
IONIC自定義動態高度SubHeader的解決方案
IONIC subheader是我們常用的一個css 屬性,但是這個subheader的高度是固定的,當然也是可以改變的,但是如果改了subheader的告訴,還要更改content的top值,稍微有些麻煩,如果是動態告訴的subheader就麻煩了,還需要動態
iOS中最簡單實用的自定義動態返回行高的cell,動態計算cell的高度
iOS專案開發中,需要動態返回行高自定義cell的場景可以說是數不過來,可以不誇張的說,只要伺服器返回的同一個欄位的文字字數無限制,那麼我們客戶端在設定的時候就要動態返回行高。 場景:1.當需要tableview展示資料時,一般頭像,暱稱,等資訊都
WF4.0以上使用代碼完整自定義動態生成執行工作流Xaml文件
load 控制 brush 類型 rpv 返回 cap 並且 sco 給大家分享一下,如何完全使用代碼自定義的創建生成工作流文件(用代碼創建Xaml文件),並且動態加載運行所生成的工作流。 工作流生成後 在Xaml文件裏的主要節點如下: 輸入輸出參數 <x
vue2入坑隨記(二) -- 自定義動態組件
blank -1 reat files 但是 name define 構建 prototype 學習了Vue全家桶和一些UI基本夠用了,但是用元素的方式使用組件還是不夠靈活,比如我們需要通過js代碼直接調用組件,而不是每次在頁面上通過屬性去控制組件的表現。下面講一下如何定
實現類似微信表情包橫向滾動翻頁的功能,運用UICollectionView,自定義UICollectionViewFlowLayout,cell左右排版 ,支持多組Cell實現。
hang sig idt 滾動翻頁 功能 details assign 實現類 targe 結合:https://blog.csdn.net/qiuhaozhou/article/details/54582741 下面是我所要的樣式的實現的代碼: .h文件如下: #i
【金蝶K3Cloud】 自定義動態表單顯示外部網頁連結。
前提: 由於想研究下,如何在金蝶K3Cloud中外掛自己的網頁或者BI 或者報表,所以反編譯了一次標準產品的經營分析平臺(BI)在金蝶K3Cloud連結的實現。 第一步: 新建動態表單 第二步: 拖一個面板控制元件,充滿整個動態表單。 第三步: 註
小白學ES 12 - 什麼是Elasticsearch的動態對映 + 如何自定義動態對映
文章目錄 1 動態對映(dynamic mapping) 1.1 什麼是動態對映 1.2 體驗動態對映 1.3 搜尋結果不一致的原因分析 2 開啟dynamic mapping策略 2.1 約束策略
Masonry適配——(7)UITableView中自定義UITableViewCell高度自適應及計算
在UITableView列表的使用中,因為在自定義的UITableViewCell中頁面相對複雜,所以會出現每一個cell都有不同的高度。這時候就需要根據實際內容進行cell的更新約束,其實說到底也就是哪些UI子檢視應該顯示,或隱藏,哪些UILabel標籤高度是這個數值,
Spring AOP+反射實現自定義動態配置校驗規則,讓校驗規則飛起來
場景小計 之前專案都是使用hibernate-validator來校驗引數,但是實際上會出現一些小問題,就是校驗規則都是通過註解的方式來完成,這樣如果專案上線了,這個引數校驗規則就沒辦法修改,如果出現校驗規則問題,就必須修改後重新緊急上線(之前因為手機
使用 dynamic_templates自定義動態索引
如果你想在執行時的增加新的欄位,你可能會開啟動態索引。雖然有時動態對映的 規則 顯得不那麼智慧,幸運的是我們可以通過設定來自定義這些規則。 當 Elasticsearch 遇到一個新的字串欄位時,它會檢測這個欄位是否包含一個可識別的日期,比如 2014-01-01。如果它看
UItextView自定義其高度,禁止滾動
/* 返回指定內容的textView控制元件高度 value:指定的控制元件內容 fontSize:指定的控制元件內容字號 width:控制元件寬度 */ - (float) heightF
mybatis自定義動態sql傳入物件
現在有一需求,要求頁面顯示懸賞列表,要求該懸賞未過期,沒有人接受以及附帶分頁查詢。 這裡我們很容易能得到滿足該需求的sql語句: select * from bounty where DeadTime > nowtime AND s
Raspberry Pi樹莓派上的自定義動態開機畫面
指南:Raspberry Pi上的自定義動態開機畫面,Raspbian Jessie 網際網路上有許多指南在Linux上建立自定義啟動螢幕,但大多數Raspbian都基於SysV init,並且不能與Raspbian現在使用的systemd介面良好。因此,我已經寫了這個指南,直接將簡單的init風格的s
APEX 自定義動態操作
自定義動態操作,可以通過一個按鈕或連結進行多個不同操作: 以下的例子是為了實現標誌當前的記錄是否已經列印的功能,點選表格中的列印欄位進行標記。 1.新建兩個項值分別存放當前記錄的ID和列印標誌is_print 2.建立動態操作,自定義型別 3.建立事件:其中兩
自定義UiTableViewCell高度
@interface DemoCell : NSObject{ UILabel *_content; } -(CGFloat)contentHeight; -(void)setContent:(NSString *)content; @end; 從上面的DemoCell來看其帶有一個UILabel物
使用Autolayout xib實現動態高度的TableViewCell
前言 最近又要做新功能了,雖然沒有什麼難點,只是獲取後端XML資料顯示到TableView,但是不是可以更簡單快速的完成呢?原來Cell的動態高度一直都是通過sizeWithFont手動計算,潛意識覺得這應該不是最好的實現方式,但由於當時時間緊不允許嘗試新技術,所以問題也就遺留了下來,這次又遇到了,時間充裕
自定義不等高cell的storyboard方法
對比自定義等高cell,需要幾個額外的步驟(iOS8開始才支援) 新增子控制元件和contentView之間的間距約束 設定tableViewCell的真實行高和估算行高 // 告
自定義等高cell(frame和masonry方式)
程式碼自定義cell方法 程式碼自定義cell(使用frame) 1.建立一個繼承自UITableViewCell的子類,比如WQDealCell 在initWithStyle:reuseIdentifier:方法中 新增子控制元件 設定子控制元件的初
AutoLayout自定義tableViewCell --- Masonry + UITableView+FDTemplateLayoutCell 純程式碼實現
AutoLayout自定義tableViewCell — Masonry + UITableView+FDTemplateLayoutCell 純程式碼實現 在被frame虐的體無完膚的樓主,在新專案開始的時候毅然決定使用Autolayout來實現專案的絕