UITableView實現QQ好友列表實戰(動態插入刪除Cell)

文章已發布在我的博客上,如需轉載,請注明原文出處

實現選擇

網上大部分的教程,都是基于修改section的hearderView來實現的,但是看QQ的好友列表,style是grouped,顯然不是使用section的header來處理。使用section的hearderView來實現的,十分簡單,網上也有很多源碼和教程,只要刷新一下dataSource然后調用就可以了。不在本次討論的范圍之內。

- (void)reloadSections:(NSIndexSet *)sections

這次我直接使用grouped的cell來做父cell,點擊后展開相應的子cell,還有動畫特效。(目測QQ好友列表沒有使用動畫特效,可能是因為好友列表過于大,內存占用問題或者是用戶體驗問題。)

封裝測試數據

使用FMDB(或者CoreData)從objc中國獲取主issue作為父級cell,文章作為subCell,具體獲取使用python和BeautifulSoup,不在本次的討論范圍之內,需要的可以查看相應的資料或者留言我,也可以在文末的項目源碼里獲取python代碼。

具體實現分析

TableView一些相關方法介紹

delegate里和點擊有關的方法如下。

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
- (NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath

當有點擊事件發生時,運行順序為。

  • willSelect
  • willDeselect
  • didDeselect
  • didSelect

插入刪除cell的方法為

- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation

記得把他們放在

[table beginUpdates];
//input insert/delete code here
[table endUpdates];
邏輯分析

在didSelect的時候執行插入代碼。

        [tableView beginUpdates];
        [tableView insertRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationTop];
        [tableView endUpdates];
        [tableView beginUpdates];
        [tableView deleteRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationRight];
        [tableView endUpdates];

其中的indexArray需要動態計算。類似這樣。

        NSMutableArray* indexArray = [NSMutableArray array];
        for (int i=1; i<=masterModel.subIuuses.count; i++) {
            NSIndexPath* path = [NSIndexPath indexPathForRow:i+indexPath.row inSection:indexPath.section];
           [indexArray addObject:path];
        }

可以實現這樣的效果。


問題分析

看起來沒有什么問題。
但是當點擊的是展開的cell下方的cell時,indexPath就會出現問題。像下面這樣。


我要點擊的是2x,但是實際上點擊的卻是4x,問題出在哪里?看這個圖片就會發現問題,原來還是那幾個方法的執行順序問題。
在執行的時候,先執行didDeselect里面的代碼,導致插入的cell被刪除,indexPath變化,然后再didSelect,當然選中的不是我們想要選中的那個cell了。

解決方案

如下圖。



只要willSelect的時候return一個新的indexPath即可,這個indexPath通過計算得出。下面是我的willSelect里的實現代碼。

-(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
    if (cell && [cell isMemberOfClass:[SIMMasterTableViewCell class]]) {
        //點擊masterCell
        if (_isShowIssues) {
            //展開狀態
            if(indexPath.row>_lastSelectMatserIndexPath.row)
                return [NSIndexPath indexPathForRow:indexPath.row-_lastModelIssuesCount inSection:indexPath.section];
            else
                return indexPath;
        }
        return  indexPath;
    }
    else if(cell)
    {
        _isSelectSubCell = YES;
        return indexPath;
        //點擊到uitableviewcell
    }
    return  indexPath;
}

最后放上一張效果圖。



項目源碼:https://github.com/XFerris/SIMObjc

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容