UITableview
從08年到現在開發過的iOS應用不計其數了,但是面試很多人的時候,發現依然很多同學在最基本的清單控件上懂得不夠深,下面就結合各方面的資料進行再一次講解。
我們都知道純代碼是效率最高的,但是在開發成本上已經越來越不如使用Storyboard成本效益高,速度快,是以本文試圖結合UIStoryboard來描述一整套方案。
簡單配置
在Storyboard中拖入UITableViewController,并且修改塗塗畫畫。
在代碼區new File生成一個基于UITableviewController的自定義類,我這裡暫時取名為Home。因為首頁就是一個複雜的清單的不在少數吧?呵呵。
然後在Identity insepctor裡修改對應的Class name,使得代碼與Storyboard産生關聯。

想要做下拉重新整理嘛?系統自帶了一個給你,并且可以自定義換标題哦。很多人真的不知道在哪兒選中,請看下圖,先選中UITableviewController,然後在頁籤中enable這個refresh選項,就自動完成了。 對應的代碼還是複制進去,就會自動觸發。
然後你需要對UITableView做一些簡單的配置,首先要選中UITableView,很多人看不到選項,是因為預設關閉了……
下圖是對UITableview的簡單配置。
Content是動态清單/靜态清單,如果是靜态的,那你基本不用寫代碼就能所見即所得,譬如“設定”頁面就可以套用。但是諸如微網誌啦,朋友圈,還是老實的用動态清單,用代碼控制。
Prototype Cells指會出現的cell有幾種類型。這個後面再講。
Style效果現場試一下就看出來了。Separator指的分隔行樣式。
然後你就需要代碼中做一些簡單的配置了,我隻列重要的,這裡不是基礎教程,基礎的還是老實的看教科書
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView //幾組
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section//每一組分别幾行
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath//每一行多高
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath//每一行分别長啥樣
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath//即将顯示某行
Load More加載更多
加載更多的UITableview擴充控件非常多,嘗試過各種第三方完美擴充後,我覺得這點小把戲也不至于需要擴充UITableview類吧?
那就是在清單追加一個Section,放在最後面,這個Section隻有一個Cell,這個自定義的cell有3種狀态,這些都可以自由發揮。
每當willDisplayCell的時候,你就設定他正在loading狀态,給使用者造成正在加載的假象,同時觸發網絡請求。
當有網絡資料傳回後,自然會insert好多内容,也輪不到這個加載更多的cell顯示的地方了,自然就釋放了。當然了,如果沒有更多内容,也可以輕松的cellForRowAtIndexPath找到唯一的cell,設定為無更多資料等狀态。
typedef enum{
JWLoadMoreNormal = 0,//點選再加載
JWLoadMoreLoading,//加載中
JWLoadMoreDone,//無更多資料
} JWLoadMoreState;
@interface LoadMoreCell : UITableViewCell
@property (strong, nonatomic) UIView *baseWhiteView;
@property (strong, nonatomic) UIActivityIndicatorView *activity;
@property (strong, nonatomic) UILabel *tipsLabel;
@property (strong, nonatomic) UIButton *loadMoreButton;
@property (nonatomic,unsafe_unretained) id <LoadMoreCellDelegate> delegate;
-(void)setupUI;
- (void)loadMore:(id)sender;
-(void)setLoadMoreStatus:(JWLoadMoreState)status;
Autolayout
做完這些,基本配置就完成了,下面需要根據設計師的要求進行自定義開發,譬如自定義cell
如上圖,密密麻麻的
autolayout的拖拽不會?你太老土了吧。xcode5的拖拽,可謂是異常簡單,隻需要點快捷菜單的pin,設定好上下左右相對關系就可以了。
建立custom的uitableviewcell基本差不多,拖出來,畫畫塗塗,建立代碼,改類名對應關系,按着“Control”拖拽關聯,等等。
我這裡隻講一個特殊的,就是圖上“圖檔”“摘要”屬于并排區域,可能沒有圖檔的文章,“摘要”就需要頂格排版。這樣的情況該怎麼設定呢?
這就得用NSLayoutConstraint的拽出來的關聯了。把”摘要“的相對距離,鎖定在一個固定的位置上,譬如”左邊欄“,通過少量的代碼計算,即可動态的修改NSLayoutConstraint.constant的距離。
NSString *url=data.img;
[self.previewImageView setClipsToBounds:YES];
if ( url!=nil && ![url isEqualToString:@""]) { //這裡是判斷有圖沒圖
[self.previewImageView setImageWithURL:[NSURL URLWithString:url] placeholderImage:[UIImage imageNamed:@"pic_default"]];
self.previewImageHeight.constant=HomeCellImageHeight;
self.previewImageWidth.constant=HomeCellImageWidth;
self.abstractLeftMargin.constant=10; //若有圖,摘要與圖的左邊距變為10
self.summaryDistanceBetweenTitle.constant=80;
}
else
{
[self.previewImageView setImage:nil];
self.previewImageHeight.constant=0; //圖檔大小全清空為0
self.previewImageWidth.constant=0;
self.abstractLeftMargin.constant=0; //若無圖,摘要與圖的左邊距變為10
[self setNeedsUpdateConstraints]; //記得強制重新整理,要不然系統懶懶的
[self.contentView layoutIfNeeded];
[self.contentView setNeedsLayout];
動态計算高度
做到這裡,恐怕大部分人都遇到一個門檻了。那就是如何動态計算cell的高度。最簡單的,就是網易新聞類,固定高度。return 44;
若是動态的,無非是建立一個cell,并且初始化構造好,然後輸出cell的最後一行控件的位置,最終給出位置。
但是這就導緻了函數運作的低效。你想,autolayout本來就夠效率低了(因為程式猿省事兒了),再為每一行計算2次,這效率能高?
我親測發現,動态排版效率是非常低的,不足以信任。
最好辦的,還是土方法。擷取對應的資料,根據自己設定的排版規則,動态的計算。土歸土,效率高啊!
TopicID *data=[threadList objectAtIndex:indexPath.row];
// NSLog(@"計算行數為%d",indexPath.row);
int height=0;
height+=17; //使用者名與頂部空間
height+=17; //使用者名高度
height+=8; //使用者名與标題之間距離
NSString *titleContent=data.title;
UIFont *titleFont = [UIFont boldSystemFontOfSize:16.0];
CGSize titleRealSize=[titleContent sizeWithFont:titleFont constrainedToSize:CGSizeMake(280, 150) lineBreakMode:NSLineBreakByTruncatingTail];
height+=titleRealSize.height;//動态計算标題高度
if (data.img!=nil && ![data.img isEqualToString:@""]) {
height+=HomeCellImageHeight;//統計圖的起始點
height+=20;
// NSLog(@"有圖");
}
else
{
NSString *abstract=data.abstract;
UIFont *abstractFont = [UIFont boldSystemFontOfSize:14.0];
CGSize abstractRealSize=[abstract sizeWithFont:abstractFont constrainedToSize:CGSizeMake(280, 300) lineBreakMode:NSLineBreakByTruncatingTail];
height+=abstractRealSize.height;
// NSLog(@"無圖");
height+=56; //統計圖的高度
height+=3;//下邊框的高度
最後别忘了Profile,計算時間,每一個細節的時間優化,最終都會展現在清單的流暢度表現上。 通過以上幾點呢,再結合現成好用的SDWebImageCache,相信大家一定可以做出真正美觀、高效的清單哦!