iOS 列表 UITableView 提速指南

UITableview

從08年到如今開發過的iOS應用不可勝數了,可是面試不少人的時候,發現依然不少同窗在最基本的列表控件上懂得不夠深,下面就結合各方面的資料進行再一次講解。面試

咱們都知道純代碼是效率最高的,可是在開發成本上已經愈來愈不如使用Storyboard性價比高,速度快,因此本文試圖結合UIStoryboard來描述一整套方案。segmentfault

簡單配置

在Storyboard中拖入UITableViewController,而且修改塗塗畫畫。xcode

在代碼區new File生成一個基於UITableviewController的自定義類,我這裏暫時取名爲Home。由於主頁就是一個複雜的列表的不在少數吧?呵呵。網絡

而後在Identity insepctor裏修改對應的Class name,使得代碼與Storyboard產生關聯。
請輸入圖片描述函數

想要作下拉刷新嘛?系統自帶了一個給你,而且能夠自定義換標題哦。不少人真的不知道在哪兒選中,請看下圖,先選中UITableviewController,而後在選項卡中enable這個refresh選項,就自動完成了。 對應的代碼仍是複製進去,就會自動觸發。
請輸入圖片描述優化

而後你須要對UITableView作一些簡單的配置,首先要選中UITableView,不少人看不到選項,是由於默認關閉了……
請輸入圖片描述ui

下圖是對UITableview的簡單配置。atom

Content是動態列表/靜態列表,若是是靜態的,那你基本不用寫代碼就能所見即所得,譬如「設置」頁面就能夠套用。可是諸如微博啦,朋友圈,仍是老實的用動態列表,用代碼控制。url

Prototype Cells指會出現的cell有幾種類型。這個後面再講。spa

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;
            height+=20;
//            NSLog(@"無圖");
        }
        height+=56; //統計圖的高度
        height+=3;//下邊框的高度

最後別忘了Profile,計算時間,每個細節的時間優化,最終都會體如今列表的流暢度表現上。 經過以上幾點呢,再結合現成好用的SDWebImageCache,相信你們必定能夠作出真正美觀、高效的列表哦!


原做者:伯樂在線 - 蔣 偉

相關文章
相關標籤/搜索