1. 程式人生 > >IOS UITableView的展開與收縮、摺疊功能

IOS UITableView的展開與收縮、摺疊功能

表格檢視的展開與收縮,就像騰訊QQ的好友列表的功能一樣在開發中我們常常用到。實現的思路有兩個:
1.定義一個分組的tableView,在頭部檢視上新增tap手勢觸發展開與收縮的事件,宣告bool值或者識別符號記錄展開與收縮的狀態。當 tableView展開的時候,重新整理那一組的cell高度為大於0的數值,那麼就展開了。當tableView收縮的時候,重新整理那一組的cell高度等於0,那麼就收縮了。
2.定義一個分組的tableView,在頭部檢視上新增tap手勢觸發展開與收縮的事件,宣告bool值或者識別符號記錄展開與收縮的狀態。當 tableView展開的時候,使用關鍵程式碼[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationTop],(就是在相應的分組當中插入cell)那麼就展開了。當tableView收縮的時候,使用關鍵程式碼[self.listTable deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationBottom],(也就是在相應的分組中刪除所有的cell)那麼就收縮了。

第一種方法如下:

 #import "ViewController.h"
 #import "SectionHeadView.h"
 #import "CustomerTableViewCell.h"

define COLOR_RGB(_R,_G,_B,_A)  [UIColor colorWithRed:_R/255.0 green:_G/255.0 blue:_B/255.0 alpha:_A]

@interface ViewController ()<UITableViewDelegate,UITableViewDataSource>{
    NSArray        *_dataSource;
    NSArray
*shopNameArr; NSMutableArray *openArr; } @property (nonatomic, strong)UITableView *myTableView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; [self getSources]; [self initalizeUserInterface]; } - (void)getSources{ _dataSource = @[@[@"周為"
,@"李超",@"周為",@"李超",@"張路",@"12",@"周為",@"李超",@"張路",@"12",@"張路",@"12",@"34",@"56",@"78",@"910"],@[@"唐進",@"周為",@"李超",@"張路",@"12",@"劉虎",@"李源",@"樊亮",@"周為",@"李超",@"張路",@"12",@"周為",@"李超",@"張路",@"12"],@[@"周心雲",@"周為",@"李超",@"張路",@"12",@"周為",@"李超",@"張路",@"12",@"周為",@"李超",@"張路",@"12",@"周為",@"李超",@"張路",@"12",@"周為",@"李超",@"張路",@"12"]]; shopNameArr = @[@"我的室友",@"睿峰朋友",@"班主任"]; openArr = [@[] mutableCopy]; for (int i = 0; i < shopNameArr.count; i++) { [openArr addObject:@"0"]; }//記錄展開狀態 } - (void)initalizeUserInterface{ self.automaticallyAdjustsScrollViewInsets =NO; [self.view addSubview:self.myTableView]; } //設定多少組 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return _dataSource.count; } //設定每組多少行 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { NSArray *arr = _dataSource[section]; return arr.count; } //設定每行多高 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if ([[openArr objectAtIndex:indexPath.section]isEqual:@"0"]) { return 0; }else{ return 45; } } //調整section頭部的間距 - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { return 30; } // 自定義頭部檢視 - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { //重用頭部檢視 static NSString *HeadViewIdentifier = @"HeadViewIdentifier"; SectionHeadView *headView = [[SectionHeadView alloc]initWithReuseIdentifier:HeadViewIdentifier]; headView.realShopName.text = [shopNameArr objectAtIndex:section]; headView.rightImageView.image = [UIImage imageNamed:@"[email protected]"];//給右邊圖片 //使用block修飾 __block SectionHeadView *weakHeadView = headView; headView.TapCallBack = ^(void){ //NSLog(@"回撥組的點選手勢:%@",[shopNameArr objectAtIndex:section]); if ([[openArr objectAtIndex:section]isEqual:@"0"]) { [openArr setObject:@"1" atIndexedSubscript:section]; [UIView animateWithDuration:0.4 animations:^{ weakHeadView.rightImageView.transform = CGAffineTransformMakeRotation(M_PI); } completion:^(BOOL finished) { //展開的時候為了防止右邊尖頭動畫執行完畢再彈回來,我們這裡重新整理的是當前組下面的cell NSMutableArray *arr = [@[] mutableCopy]; NSArray *brr = _dataSource[section]; for (int i = 0; i < brr.count; i++) { [arr addObject:[NSIndexPath indexPathForRow:i inSection:section]]; } //重新整理特定的cell [self.myTableView reloadRowsAtIndexPaths:arr withRowAnimation:UITableViewRowAnimationRight]; }]; }else if ([[openArr objectAtIndex:section]isEqual:@"1"]){ [openArr setObject:@"0" atIndexedSubscript:section]; [UIView animateWithDuration:0.4 animations:^{ weakHeadView.rightImageView.transform = CGAffineTransformMakeRotation(0); } completion:^(BOOL finished) { //重新整理某一組 [self.myTableView reloadSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationLeft]; }]; } }; return headView; } //處理刪除邏輯 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{ if (editingStyle != UITableViewCellEditingStyleDelete) { //如果不是刪除狀態直接返回 return; } NSLog(@"你真的刪除了我"); //將編輯狀態置為NO,一定要設定為NO才會有那個動畫效果 [_myTableView setEditing:NO animated:YES]; } -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"HomeCell"; CustomerTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (!cell) { cell = [[CustomerTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; } cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;/ cell.layer.masksToBounds = YES;//設定超出父檢視的部分不顯示,不設定會有出現重疊的問題 cell.selectionStyle = UITableViewCellSelectionStyleNone; cell.nameLabel.text = _dataSource[indexPath.section][indexPath.row]; return cell; } -(UITableView *)myTableView { if (_myTableView == nil) { _myTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 64,375,603) style:UITableViewStylePlain]; _myTableView.delegate = self; _myTableView.dataSource = self; // _myTableView.backgroundColor = COLOR_RGB(239, 239, 244, 1); _myTableView.separatorColor = [UIColor redColor]; _myTableView.sectionFooterHeight = 0.0; //設定為不顯示分割線過後,組上的分割線也會不顯示 _myTableView.separatorStyle = UITableViewCellSeparatorStyleNone; } return _myTableView; } }

第二種方法:這種方法更為高大上,效率也更高,更規範,推薦使用這種。- (void)cellInsertOrDelete:(BOOL)insert是一個點選分組頭部檢視的響應事件,引數為一個bool值用於判斷是展開還是收縮。

// 表格檢視的刪除與插入,刪除就是收縮,插入就是展開。

- (void)cellInsertOrDelete:(BOOL)insert{

//    1. 這個方法用於在呼叫插入,刪除,選擇方法時,同時有動畫效果。
//    2. 用endUpdate能動畫改變行高,而無需relaod這個cell。
//    3. beginUpdate和endUpdate成對使用,其包含的block裡面,如果沒有插入刪除,選擇的方法被使用。有可能導致這個table view的一些屬性失效,例如行的數量。
//    4. 不應該在這個block範圍裡呼叫 reloadData,或者reloadRowsAtIndexPaths。一旦使用,必須自己執行和管理自己的動畫效果。
//    第三點和第四點比較重要。也是導致閃退的原因。reloadData會引起,獲取單元格高度,以及cell的重新載入。這會導致一些動畫對應的行號產生變化。從而閃退。

//    beginUpdates方法和endUpdates方法是什麼呢?
//
//    這兩個方法,是配合起來使用的,標記了一個tableView的動畫塊。
//
//    分別代表動畫的開始開始和結束。
//
//    兩者成對出現,可以巢狀使用。
//
//    一般,在新增,刪除,選擇 tableView中使用,並實現動畫效果。
//
//    在動畫塊內,不建議使用reloadData方法,如果使用,會影響動畫。

//    一般在UITableView執行:刪除行,插入行,刪除分組,插入分組時,使用!用來協調UITableView的動畫效果。
    [self.listTable beginUpdates];
    NSMutableArray *indexPaths = [NSMutableArray arrayWithCapacity:self.datas.count];
    [self.datas enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        NSIndexPath *indexP = [NSIndexPath indexPathForRow:idx inSection:0];
        [indexPaths addObject:indexP];
    }];
    if (insert) {
        [self.listTable insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationTop];
    }else{
        [self.listTable deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationBottom];
    }
    [self.listTable endUpdates];
}

再次解釋下:
/*
UITableView的 beginUpdates方法和endUpdates方法是什麼呢?

這兩個方法,是配合起來使用的,標記了一個tableView的動畫塊。
分別代表動畫的開始開始和結束。
兩者成對出現,可以巢狀使用。
一般,在新增,刪除,選擇 tableView中使用,並實現動畫效果。
在動畫塊內,不建議使用reloadData方法,如果使用,會影響動畫。

如果我們的UITableView是分組的時候,我們如果刪除某個分組的最後一條記錄時,相應的分組也將被刪除。所以,必須保證UITableView的分組,和cell同時被刪除。
所以,就需要使用beginUpdates方法和endUpdates方法,將要做的刪除操作“包”起來。
*/

相關推薦

IOS UITableView展開收縮摺疊功能

表格檢視的展開與收縮,就像騰訊QQ的好友列表的功能一樣在開發中我們常常用到。實現的思路有兩個: 1.定義一個分組的tableView,在頭部檢視上新增tap手勢觸發展開與收縮的事件,宣告bool值或者識別符號記錄展開與收縮的狀態。當 tableView展開的時

iOS中UIWebViewWKWebViewJavaScriptOC互動Cookie管理看我就夠(下)

前言在前面的文章中,我們介紹了UIWebView、WKWebView一些使用,與JS的互動和一些坑,相信看過的小夥伴們,已經大概清楚了吧,如果有問題,歡迎提問。本文是本系列文章的最後一篇,主要為小夥伴們分享下Safari除錯、與前端的配合以及實際應用中一些需求的實現等:關於文

cell展開收縮 聯動效果

#import "EFPayViewController.h" #import "EFDetailMessageTableViewCell.h" static NSString *EFDetailMessageTableViewCellID = @"EFDetailMes

Cocos2d-x 3.x 頭像選擇器,本地相簿拍照+頭像編輯功能(AndroidIOS雙平臺實現)

大連遊戲行業不是太發達,最後選擇在一家應用外包公司工作,在工作和業餘學習過程中積累了一點微不住道的經驗,希望分享給熱愛遊戲的小夥伴們。 在應用開發過程中會常常有使用者上傳頭像的功能,在網上找了N多資料發現沒有人具體介紹過該用cocos2d-x實現。這篇文章就來介紹一下如何在

iOS開發-UI控制元件:可摺疊展開UITableView

在之前的專案中自己寫了一個可以摺疊展開的UITableView. 思路如下: 1. 使用一個字典儲存Table中每個Section開啟&摺疊的狀態, 然後在下面的方法中, 字典返回1則展開cell, 反之摺疊cell   - (NSInteger)tableView

【18.7.25】掃雷c語言小遊戲,展開防第一次炸死功能

遞迴看了N遍終於寫出來了展開功能,心塞。 上效果圖 開啟程式碼,control+F5,走! 輸入1開始遊戲 密集恐懼症,心裡一萬隻草泥馬路過。。。 未開啟前都是‘*’號,玩家根據行標和列標輸入需要掃雷的位置 就快要贏了,當然這個難度可能比較低,但

Android工程師開發iOSAndroid中對應功能的控制元件

iOS中和安卓控制元件應用還是差不的,從控制元件的命名上我們就能看出來,下面來介紹一下吧: ios中UILabel 對應Android 中TextView ios中UIImage對應Android 中ImageView 圖片控制元件 ios中UIButton對應An

Linux基礎命令(三):重定向展開引用——catsortuniqgrepwcheadtailtee

I/O重定向 通過這個工具,可以重定向命令的輸入輸出,命令的輸入來自檔案,而輸出也存到檔案。 也可以把多個命令連線起來組成一個強大的命令管道。 cat — 連線檔案 sort — 排序文字行 uniq — 報道或省略重複行 grep — 列印匹配行 wc — 列印

androidIOS 基於webview HTML 的整合

知識點: 1)android 和 html 的整合 2)html 如何通過javascript 判斷 客戶端是 android 還是 IOS 3)IOS 和android 的整合 (我不懂IOS 的oc 開發,所以這部分我省略。。。。我是和我的一個IOS同事一同測試過的,html 是我寫的)

微信小程式——轉發功能踩坑(辨別到群個人多個轉發按鈕轉發帶引數)總結

小程式的轉發功能已經封裝好了,可以通過在 Page 中定義 onShareAppMessage 函式,設定該頁面的轉發資訊。 eg: wxml <button open-type="share">轉發</button> js

iOS應用呼叫系統打電話發簡訊和發郵件功能

摘要: 在應用程式內,呼叫系統的功能來實現打電話、發簡訊和發郵件,通過電話號碼或者郵箱,直接跳轉到系統的功能介面。 PS:除錯好像只能真機除錯,模擬器沒有反應,真機就可以跳轉,不知道是不是必須真機,但方法肯定是可行的。 1、打電話 應用內呼叫系統打電話有兩種方式: 1

如何監聽CollapsingToolbarLayout的展開摺疊

使用官方提供的 AppBarLayout.OnOffsetChangedListener就能實現了,不過要封裝一下才好用。 自定義一個繼承了 AppBarLayout.OnOffsetChangedListener的類,這裡命名為AppBarStateChangeL

iOS】高德地圖MAMapKit的使用:地圖顯示新增大頭針導航定位功能介紹

4、 引入高德地圖依賴系統庫檔案: 說明: 1.備註中,2D表示使用2D柵格地圖需要的系統檔案,3D表示使用3D向量地圖需要的系統檔案、Search表示使用搜索庫需要的系統檔案,3D(V3.X.X)表示3D向量地圖V3.0.0以後版本需要新增的庫。 2.SystemConfiguration.f

可控制的Select的展開摺疊

<Object type="application/x-oleobject" id=Shell classid="clsid:F935DC22-1CF0-11D0-ADB9-00C04FD58A0B"></Object><SELECT id=cb

【Ionic】Ionic實現iOSAndroid端程式碼『熱更新』Android升級下載功能 ( v1.3.x版本 )

熱更新的好處 通常ionic原始碼可包括(HTML,JavaScript,CSS檔案和其他資源),往常我們必須通過提交程式到應用市場,經過漫長的稽核後才可讓使用者更新,每改動一個小地方都需要重新打新版本。 現在ionic通過使用cordova外掛cordov

iOSUITableView Cell自定義單選功能

今天分享下cell的單選,自定義的,不是下圖這種網上找到的打對勾的,我搜了好久,基本上都是打對勾的文章,就決定自己寫一篇。基本上自己的app都會有一個風格吧,咱也不能一直用打對勾的方式去做(看起來是不是很low)。 我們要實現的是下面的這種形式。瞬間好看了

listview巢狀gridview,並實現grid元素部分顯示以及點選展開摺疊

有時我們需要用GridView顯示目錄列表,有時甚至是二級的,即listview每一個item裡面又各自嵌入一個gridview,但是當二級目錄(資料條目)的數量過多時,介面會比較臃腫,這時我們就想要有類似展開與摺疊的效果,作者採用的策略是資料分段的分別顯示,其中對於顯示邊

iOS 鍵盤彈出回收介面上移和下移

//新增通知,來控制鍵盤和輸入框的位置     [[NSNotificationCenterdefaultCenter] addObserver:selfselector:@selector(ke

Android ExpandableListView列表全部展開全部收縮

Android ExpandableListView列表全部展開與全部收縮的解決方法: 列表全部展開程式碼:for (int i = 0; i < adapter.getGroupCount()

ios 漢字轉碼 (漢字utf8Unicode轉漢字

Unicode轉化為漢字: + (NSString *)replaceUnicode:(NSString *)unicodeStr {           NSString *tempStr1 = [unicodeStrstringByReplacingOccurrencesOfString:@"\\u