1. 程式人生 > >【技巧】UITableView 在UITableViewStylePlain模型下,取消headerView的黏結性,不浮動

【技巧】UITableView 在UITableViewStylePlain模型下,取消headerView的黏結性,不浮動

        UITableView使用UITableViewStylePlain樣式時,section的header與footer會在滾動過程中固定在頂部,這個互動很不錯。如果要阻止這個互動,那麼辦法有幾個:
1. 樣式改成UITableViewStyleGrouped,但是在iOS6上需要做很多樣式調整才能達到與UITableViewStylePlain一致;
2. 每個section多加行來模擬header或footer,但是程式碼維護難度更大;
3. 繼承UITableView,覆蓋方法-allowsHeaderViewsToFloat或-allowsFooterViewsToFloat,但是使用了私有API稽核有風險;
4. 自定義header或者footer阻止浮動, 重寫tableview的frame
5. 假裝cell為header。

        以上種種方法帶有破壞性,入侵性:動不動修改frame和contentInset。現在介紹一個巧妙方法,使用簡單。

設計思路:

        普通的section,cell多的話滑動時候超過一屏的高度,綠色的header會停留在section的top並浮動。如圖1:


       那麼如果section中的cell為空,它是不會浮動的;基於這個原理,可以巧妙的將header單獨拎出來。如圖2:試想分拆後的每一個section,只有第一個帶有header,且不會浮動。為了擴充套件性,將footer也算進去。


        一圖省千語啊

UITableViewDelegate UITableViewDataSource

將原始的section數量乘以3,得到header的section,cell的section,footer的section。

#pragma mark —————header——————
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    if (section%3 == 0) {
        /*正常的header 高度*/
        return headerHeight;
    }
    return 0;
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    if (section%3 == 0) {
        /*正常的header*/
        return headerView;    
    }
    
    return nil;
}
#pragma mark —————cell——————
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (section%3 == 1) {
        /*正常的cell 高度*/
        return cellHeight;    
    }
    return 0;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (section%3 == 1) {
        /*正常的cell*/
        return cell;    
    }

    return nil;
}

#pragma mark —————footer——————
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
    if (section%3 == 2) {
        /*正常的footer 高度*/
        return footerHeight;    
    }
    return 0;
}


- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
    if (section%3 == 2) {
        /*正常的footer*/
        return footerView;    
    }
    return nil;
}

(完)