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中UIWebView與WKWebView、JavaScript與OC互動、Cookie管理看我就夠(下)
前言在前面的文章中,我們介紹了UIWebView、WKWebView一些使用,與JS的互動和一些坑,相信看過的小夥伴們,已經大概清楚了吧,如果有問題,歡迎提問。本文是本系列文章的最後一篇,主要為小夥伴們分享下Safari除錯、與前端的配合以及實際應用中一些需求的實現等:關於文
cell展開與收縮 聯動效果
#import "EFPayViewController.h" #import "EFDetailMessageTableViewCell.h" static NSString *EFDetailMessageTableViewCellID = @"EFDetailMes
Cocos2d-x 3.x 頭像選擇器,本地相簿與拍照+頭像編輯功能(Android、IOS雙平臺實現)
大連遊戲行業不是太發達,最後選擇在一家應用外包公司工作,在工作和業餘學習過程中積累了一點微不住道的經驗,希望分享給熱愛遊戲的小夥伴們。 在應用開發過程中會常常有使用者上傳頭像的功能,在網上找了N多資料發現沒有人具體介紹過該用cocos2d-x實現。這篇文章就來介紹一下如何在
iOS開發-UI控制元件:可摺疊展開的UITableView
在之前的專案中自己寫了一個可以摺疊展開的UITableView. 思路如下: 1. 使用一個字典儲存Table中每個Section開啟&摺疊的狀態, 然後在下面的方法中, 字典返回1則展開cell, 反之摺疊cell - (NSInteger)tableView
【18.7.25】掃雷c語言小遊戲,展開與防第一次炸死功能
遞迴看了N遍終於寫出來了展開功能,心塞。 上效果圖 開啟程式碼,control+F5,走! 輸入1開始遊戲 密集恐懼症,心裡一萬隻草泥馬路過。。。 未開啟前都是‘*’號,玩家根據行標和列標輸入需要掃雷的位置 就快要贏了,當然這個難度可能比較低,但
Android工程師開發iOS之與Android中對應功能的控制元件
iOS中和安卓控制元件應用還是差不的,從控制元件的命名上我們就能看出來,下面來介紹一下吧: ios中UILabel 對應Android 中TextView ios中UIImage對應Android 中ImageView 圖片控制元件 ios中UIButton對應An
Linux基礎命令(三):重定向、展開與引用——cat、sort、uniq、grep、wc、head、tail、tee
I/O重定向 通過這個工具,可以重定向命令的輸入輸出,命令的輸入來自檔案,而輸出也存到檔案。 也可以把多個命令連線起來組成一個強大的命令管道。 cat — 連線檔案 sort — 排序文字行 uniq — 報道或省略重複行 grep — 列印匹配行 wc — 列印
android、IOS 基於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實現iOS與Android端程式碼『熱更新』與Android升級下載功能 ( v1.3.x版本 )
熱更新的好處 通常ionic原始碼可包括(HTML,JavaScript,CSS檔案和其他資源),往常我們必須通過提交程式到應用市場,經過漫長的稽核後才可讓使用者更新,每改動一個小地方都需要重新打新版本。 現在ionic通過使用cordova外掛cordov
【iOS】UITableView 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 漢字轉碼 (漢字與utf8、Unicode轉與漢字
Unicode轉化為漢字: + (NSString *)replaceUnicode:(NSString *)unicodeStr { NSString *tempStr1 = [unicodeStrstringByReplacingOccurrencesOfString:@"\\u