iOS-個人整理19 - UITableViewCell自定義,cell高度的自適應(yīng)

一、UITableViewCell的自定義

UITableVie中系統(tǒng)的Cell共提供了四種默認(rèn)樣式,
分別是:UITableVieCellStyleDefault //只有一個label
UITableVieCellStyleValue1 //兩個label
UITableVieCellStyleValue2 //兩個label瘟芝,布局不同于上面的
UITableVieCellStyleSubtitle //帶副標(biāo)題但是在實際使?用過程中,Cell樣式的布局上千差萬別,

比如:

沒錯易桃,聊天界面也是TableViewCell。
為了滿足各種奇葩的需求和精美的設(shè)計锌俱,需要我們自定義cell
我們也就可以在一個tableView里放各種不同的Cell

方法也不復(fù)雜
首先創(chuàng)建一個繼承于UITableViewCell的類CustomCell
在CustomCell.h中聲明屬性晤郑,這些屬性就是要添加到自定義cell上的Label,ImageView等等

#import <UIKit/UIKit.h>  
@interface CustomCell : UITableViewCell   
@property (nonatomic,retain)UILabel* nameLabel;//顯示名字  
@end  

然后在CustomCell.m中對聲明對屬性寫好懶加載

#import "CustomCell.h"  
  
@implementation CustomCell  
  
//姓名標(biāo)簽的初始化  
-(UILabel *)nameLabel  
{  
    if (!_nameLabel) {  
        _nameLabel = [[UILabel alloc]initWithFrame:CGRectMake(80, 10, 120, 30)];  
        [self.contentView addSubview:_nameLabel];  
    }  
    return _nameLabel;  
}  
@end  

最后在UITableView的注冊單元格和填充單元格的代碼中替換系統(tǒng)的UITableViewCell

 //注冊單元格,在ViewDidLoad方法中  
  
    [self.tableView registerClass:[CustomCell class] forCellReuseIdentifier:@"CELL"];    
    
//重用隊列,這在單元格填充的方法內(nèi)  
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {  
  
   //這里用CustomCell替換原來的UITableViewCell  
   CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CELL" forIndexPath:indexPath];  

}

總體思路就是這樣造寝,主要不同是這個cell怎么自定義磕洪,里面加多少label,imageView诫龙,怎么布局析显,就是個人的事了。

二签赃、cell高度的自適應(yīng)

有時候要根據(jù)內(nèi)容調(diào)整cell的高度叫榕,要用到cell返回高度的代理方法

//返回高度的代理方法  
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath  

還需要對內(nèi)容的高度進(jìn)行一定的計算,這里先提供一種計算文本寬高的方法
這是一個自寫函數(shù)姊舵,核心是使用了系統(tǒng)的boundingRectWithSize:CGSizeMake(width,height) optins:() attributes:()context:方法
這個方法需要我們提供一個寬度一個高度,如果寬度設(shè)置為MaxFloat寓落,高度給定括丁,則最后計算出一個CGRect會根據(jù)內(nèi)容content計算出相應(yīng)的寬度。
同樣伶选,如果高度設(shè)置為MaxFloat史飞,最后會計算出一個CGRect,其高度是根據(jù)content計算出的

options:這個參數(shù)比較重要

1.NSStringDrawingUsesLineFragmentOrigin:
繪制文本時使用 line fragement origin 而不是 baseline origin仰税。
2.NSStringDrawingUsesFontLeading:
計算行高時使用行距构资。(字體大小+行間距=行距)
3.NSStringDrawingTruncatesLastVisibleLine:
如果文本內(nèi)容超出指定的矩形限制,文本將被截去并在最后一個字符后加上省略號陨簇。如果沒有指定NSStringDrawingUsesLineFragmentOrigin選項吐绵,則該選項被忽略。
4.計算布局時使用圖元字形(而不是印刷字體)河绽。
Use the image glyph bounds (instead of the typographic bounds) when computing layout.
attributes:文本屬性己单,一個字典,里面包含了文字的各種屬性耙饰,這里沒細(xì)看纹笼,僅供參考
(1)NSKernAttributeName: @10 調(diào)整字句 kerning 字句調(diào)整
(2)NSFontAttributeName : [UIFont systemFontOfSize:_fontSize] 設(shè)置字體
(3)NSForegroundColorAttributeName :[UIColor redColor] 設(shè)置文字顏色
(4)NSParagraphStyleAttributeName : paragraph 設(shè)置段落樣式
(5)NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
paragraph.alignment = NSTextAlignmentCenter;
(6)NSBackgroundColorAttributeName: [UIColor blackColor] 設(shè)置背景顏色
(7)NSStrokeColorAttributeName設(shè)置文字描邊顏色,需要和NSStrokeWidthAttributeName設(shè)置描邊寬度苟跪,這樣就能使文字空心.
context:上下文廷痘。包括一些信息,例如如何調(diào)整字間距以及縮放件已。最終笋额,該對象包含的信息將用于文本繪制。但是沒用過拨齐,還不懂鳞陨,該參數(shù)可為 nil 。

#pragma mark -- 計算寬窄的函數(shù)  
-(float)autoCalculateWidthOrHeight:(float)height  
                             width:(float)width  
                          fontsize:(float)fontsize  
                           content:(NSString*)content  
{  
    //計算出rect  
    CGRect rect = [content boundingRectWithSize:CGSizeMake(width, height)   
                                        options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading   
                                     attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontsize]} context:nil];  
      
    //判斷計算的是寬還是高  
    if (height == MAXFLOAT) {  
        return rect.size.height;  
    }  
    else  
        return rect.size.width;  
}  

有了上面這個看起來有點(diǎn)復(fù)雜的方法,我們就可以調(diào)用它計算出應(yīng)有的寬或者高了


//計算出nameLabel的寬度,高度為20厦滤,字體大小為17  
  _nameWidth = [self autoCalculateWidthOrHeight:20 width:MAXFLOAT fontsize:17 content:name];  
//  RootTableViewController.m  
  
#import "RootTableViewController.h"  
#import "CustomTableViewCell.h"  
  
@interface RootTableViewController ()  
  
@property (nonatomic,retain)NSArray *contentArray;  
  
@end  
  
@implementation RootTableViewController  
  
- (void)viewDidLoad {  
    [super viewDidLoad];  
      
    self.navigationItem.title = @"自定義cell";        
    //注冊cell  
    [self.tableView registerClass:[CustomTableViewCell class] forCellReuseIdentifier:@"CELL"];  
           
}  
    
#pragma mark - Table view data source  
  
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {  
#warning Incomplete implementation, return the number of sections  
    return 1;  
}  
  
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {  
#warning Incomplete implementation, return the number of rows  
    return 3;  
}  
  
#pragma mark -- 單元格填充  
  
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {  
    CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CELL" forIndexPath:indexPath];  
    cell.tag =1000;  
    //對cell填寫內(nèi)容  
    cell.newsImageView.image = [UIImage imageNamed:@"placeholder.jpg"];  
    cell.titleLabel.text = [NSString stringWithFormat:@"第%ld條",indexPath.row];  
    cell.abstractLabel.text = _contentArray[indexPath.row];  
    cell.commentNumLavel.text = @"1.6萬跟帖";  
  
    return cell;  
}  
  
//返回單元格的高度  
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath  
{  
    //數(shù)據(jù)數(shù)組  
    _contentArray = [[NSArray alloc]initWithObjects:@"不信這都不過援岩。我是高二的文科生,政治學(xué)得不怎么樣掏导, 
老爸就叫我抄了老師的號碼說是跟老師探討怎么督促我學(xué)習(xí)什么的…享怀。結(jié)果兩個月后,政治老師被我爸拿下了………趟咆。- -添瓷!我現(xiàn)在更不知道政治該怎么辦……。 ",  
@"聽我們這的一位老師傅講的值纱。鳞贷。。前面一輛寶馬虐唠,開車的是個妹子搀愧,后面跟著一個皮卡,塊紅綠燈了疆偿,到路口咱筛,剛好黃燈,那妹子直接剎車杆故,當(dāng)然了迅箩,你們懂的, 
皮卡沒反應(yīng)過來处铛,再加上剎車不如人寶馬快饲趋,果斷撞上了,其實要是個爺們開那寶馬罢缸,黃燈也就闖過去了篙贸,那皮卡就這么想的。然后那妹子走下車來枫疆,看車撞了爵川, 
蹲地上就哭。那皮卡里的少年出來愣了息楔,扶著那妹子說寝贡,妹妹你別哭了,該哭的是我值依。圃泡。。 ",@"剛剛從臺灣旅游回來愿险,體會到了傳說中的民風(fēng)淳樸颇蜡。价说。。风秤。鳖目。 
默默地分割。缤弦。领迈。。碍沐。狸捅。話說住在嘉義那天去夜市,找了一家店吃宵夜累提,點(diǎn)了一個特色的火雞飯和鹵肉飯尘喝,小碗那種,總共才40臺幣斋陪,十塊rmb都不到瞧省, 
中途我出去買鹽酥雞,我朋友出去買飲料鳍贾,吃完我們就抹抹嘴巴走了(我們都以為對方付過錢了)走到半路想起來落了圍巾,回去拿交洗,我跟店員打了招呼骑科, 
拿好圍巾出店門,想想不對构拳,問朋友付錢沒咆爽?她也搖頭,于是回到店里問那個靦腆的小伙子置森,怎么不問我們收錢斗埂,他說:看你們剛剛走得急。凫海。呛凶。", nil nil];  
      
    //根據(jù)內(nèi)容計算高度  
    CGRect rect = [_contentArray[indexPath.row] boundingRectWithSize:CGSizeMake(CGRectGetWidth(self.view.frame)-120, MAXFLOAT)   
            options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading   
            attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17]} context:nil];  
    //再加上其他控件的高度得到cell的高度  
      
    return rect.size.height + 20 + 20;  
}      
@end  

自定義的cell

//  CustomTableViewCell.h  
  
#import <UIKit/UIKit.h>  
  
@interface CustomTableViewCell : UITableViewCell  
  
//創(chuàng)建三個label,一個imageView  
@property (nonatomic,retain)UILabel* titleLabel;//標(biāo)題  
@property (nonatomic,retain)UILabel* abstractLabel;//摘要  
@property (nonatomic,retain)UILabel* commentNumLavel;//跟帖數(shù)量  
@property (nonatomic,retain)UIImageView* newsImageView;//新聞圖片  
  
@end  
//  CustomTableViewCell.m  
  
#import "CustomTableViewCell.h"  
  
@implementation CustomTableViewCell  
  
#pragma mark -- 懶加載  
  
//左側(cè)圖片  
-(UIImageView *)newsImageView  
{  
    if (!_newsImageView) {  
        _newsImageView = [[UIImageView alloc]initWithFrame:CGRectMake(5, 10, 80, 80)];  
        [self.contentView addSubview:_newsImageView];  
        _newsImageView.image = [UIImage imageNamed:@"placeholder.jpg"];  
        //設(shè)置圓角  
        _newsImageView.layer.cornerRadius = 5;  
        _newsImageView.layer.masksToBounds = YES;  
    }  
    return _newsImageView;  
}  
  
//標(biāo)題  
-(UILabel *)titleLabel  
{  
    if (!_titleLabel) {  
        _titleLabel = [[UILabel alloc]initWithFrame:CGRectMake(100, 5, CGRectGetWidth(self.frame)-120, 20)];  
        [self.contentView addSubview:_titleLabel];  
        _titleLabel.backgroundColor = [UIColor colorWithRed:247/255.0 green:162/255.0 blue:120/255.0 alpha:1];  
    }  
    return _titleLabel;  
}  
  
//摘要  
-(UILabel *)abstractLabel  
{  
    if (!_abstractLabel) {  
        _abstractLabel = [[UILabel alloc]initWithFrame:CGRectMake(100, 25, CGRectGetWidth(self.frame)-120, 70)];  
        [self.contentView addSubview:_abstractLabel];  
        _abstractLabel.backgroundColor =  [UIColor colorWithRed:200/255.0 green:233/255.0 blue:160/255.0 alpha:1];  
          
        //設(shè)置行數(shù)行贪,這里很重要漾稀,0意味著行數(shù)自適應(yīng)  
        _abstractLabel.numberOfLines = 0;  
          
        //設(shè)置字體  
        _abstractLabel.font = [UIFont fontWithName:@"28=蒙納幼雅麗" size:15];  
    }  
      
    //根據(jù)cell重新調(diào)整label的高度  
    CGRect labelRect = _abstractLabel.frame;  
    labelRect.size.height = CGRectGetHeight(self.frame)-20-20;  
    _abstractLabel.frame = labelRect;  
      
    return _abstractLabel;  
}  
//跟帖數(shù)  
-(UILabel *)commentNumLavel  
{  
    if (!_commentNumLavel) {  
        _commentNumLavel = [[UILabel alloc]initWithFrame:CGRectMake(CGRectGetWidth(self.frame)-100,   
         CGRectGetHeight(self.frame)-20, 80, 15)];  
        [self.contentView addSubview:_commentNumLavel];  
        _commentNumLavel.backgroundColor = [UIColor colorWithRed:109/255.0 green:211/255.0 blue:206/255.0 alpha:1];  
          
        //設(shè)置字體  
        _commentNumLavel.font = [UIFont fontWithName:@"testfont" size:12];  
    }  
    return _commentNumLavel;  
}      
@end  

效果

三、在可視化下讓cell自適應(yīng)高度

在使用xib或者storyBoard時建瘫,同樣可以在heightForCell的代理方法里調(diào)整cell的高度
但是cell上面的label要同時改變大小崭捍,就有所不同。
可以使用拉約束的方法啰脚,如圖我這里是一個UITableViewCell的xib文件殷蛇,給上面的contentLabel拉了四個約束,具體怎么拉看autolayout
分別規(guī)定了這個Label 到cell上邊緣的距離,到cell下邊緣的距離粒梦,到cell左邊緣的距離亮航,已經(jīng)label的width給定值。
這樣谍倦,cell的高度變化塞赂,label為隨之變化

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市昼蛀,隨后出現(xiàn)的幾起案子宴猾,更是在濱河造成了極大的恐慌,老刑警劉巖叼旋,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件仇哆,死亡現(xiàn)場離奇詭異,居然都是意外死亡夫植,警方通過查閱死者的電腦和手機(jī)讹剔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來详民,“玉大人延欠,你說我怎么就攤上這事∩蚩纾” “怎么了由捎?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長饿凛。 經(jīng)常有香客問我狞玛,道長,這世上最難降的妖魔是什么涧窒? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任心肪,我火速辦了婚禮,結(jié)果婚禮上纠吴,老公的妹妹穿的比我還像新娘硬鞍。我一直安慰自己,他們只是感情好戴已,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布膳凝。 她就那樣靜靜地躺著,像睡著了一般恭陡。 火紅的嫁衣襯著肌膚如雪蹬音。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天休玩,我揣著相機(jī)與錄音著淆,去河邊找鬼劫狠。 笑死,一個胖子當(dāng)著我的面吹牛永部,可吹牛的內(nèi)容都是我干的独泞。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼苔埋,長吁一口氣:“原來是場噩夢啊……” “哼懦砂!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起组橄,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤荞膘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后玉工,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體羽资,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年遵班,在試婚紗的時候發(fā)現(xiàn)自己被綠了屠升。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡狭郑,死狀恐怖腹暖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情翰萨,我是刑警寧澤微服,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站缨历,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏糙麦。R本人自食惡果不足惜辛孵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望赡磅。 院中可真熱鬧魄缚,春花似錦、人聲如沸焚廊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽咆瘟。三九已至嚼隘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間袒餐,已是汗流浹背飞蛹。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工谤狡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人卧檐。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓墓懂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親霉囚。 傳聞我的和親對象是個殘疾皇子捕仔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評論 2 345

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