一、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為隨之變化