關於點擊TableviewCell的子內容收放問題,拿到它的第一個思路就是,數組
方法一:測試
運用UITableview自己的代理來處理相應的展開收起:ui
1.代理:- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPathspa
2. 須要聲明一個全局BOOL變量isOpen,記錄當前cell的狀態(展開/收起),聲明一個NSInterge類型selectedIndexRow,記錄選擇的cell的row,切記初始化相應的屬性。代理
(ps:在網上看到不少文章都是這樣,可是真的用的時候,發現,咱們須要另外聲明一個NSIndexPath類型的selectedIndex,或者用到時候本身運用記錄的row生成也可,也許確實是我本身畫蛇添足)調試
3.首先,咱們須要理清本身需求的邏輯關係,何時展開/收起,展開收起時它的高度,個數等等有什麼變化------->來進行代理,數據源方法的書寫blog
下面也是展現tableview時的調用順序繼承
1>://返回cell個數
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
2>://返回每行的高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
3>://請求數據元代理爲tableView插入須要的cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
4>://監聽點擊的cell
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath索引
代碼:事件
#pragma mark --------- UITableViewDelegate && UITableViewDataSource -----
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.scoreDataArray.count;//根據本身的具體須要返回
}
//計算高度---根據需求,動態計算內容的高度
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
//indexPath.row == selectedIndex.row &&
NSLog(@"heightForRow %ld",(long)selectedIndex.row);
if (indexPath.row == selectedIndex.row && selectedIndex != nil)
{
if (isOpen == YES)
{
//內部內容直接忽略便可
YunGangScoreData *data = [[YunGangScoreData alloc] init];
//data = self.scoreDataArray[indexPath.row];
data = self.scoreDataArray[selectedIndex.row];
if (data.detailTypeArray.count>0)
{
self.cellHeight = 60+data.detailTypeArray.count*40;
return self.cellHeight;
}
return 60;
}
else
{
return 60;
}
}
return 60;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//indexPath.row == selectedIndex.row &&
NSLog(@"cellForRow %ld",(long)selectedIndex.row);
if (indexPath.row == selectedIndex.row && selectedIndex != nil)
{//內部內容直接忽略便可
//若是是展開
if (isOpen == YES)
{
YunGangScoreTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"YunGangScoreTableViewCell"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.data = self.scoreDataArray[selectedIndex.row];
cell.isOpen = YES;
return cell;
}
else
{//收起
YunGangScoreTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"YunGangScoreTableViewCell"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.data = self.scoreDataArray[selectedIndex.row];
cell.isOpen = NO;
return cell;
}
}
else//不是自身
{
YunGangScoreTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"YunGangScoreTableViewCell"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.data = self.scoreDataArray[indexPath.row];
cell.isOpen = NO;
return cell;
}
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//將索引加到數組中
NSArray *indexPaths = [NSArray arrayWithObject:indexPath];
//判斷選中不一樣row狀態時候
//我本身加上的,看好多文章沒有,可能我錯了,selectedIndex = indexPath;
NSLog(@"%ld",(long)selectedIndex.row);
if (selectedIndex != nil && indexPath.row == selectedIndex.row)
{//將選中的和全部索引都加進數組中
// indexPaths = [NSArray arrayWithObjects:indexPath,selectedIndex, nil];
isOpen = !isOpen;
}
else if (selectedIndex != nil && indexPath.row != selectedIndex.row)
{
indexPaths = [NSArray arrayWithObjects:indexPath, selectedIndex,nil];
isOpen = YES;
}
//記下選中的索引
selectedIndex = indexPath;
//刷新
[tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
}
大體運用的就這些內容,本身看着調試下。。。
方法二: 我試了上面方法,發現可能出現刷新等問題,也就換了下面的
這裏用section當作第一個cell,而後加載view到section上,添加手勢來做爲點擊事件,展開的內容加載cell(第二個)
直接上代碼:
1.聲明屬性:
//cell收放,以及記錄cell的selectedIndex
NSMutableDictionary *_showDic;//用來判斷分組展開與收縮的
int index;
2.用section的個數來展現未點擊時的tableview內容
3計算點擊每一個section以後展開的cell的個數
4.這裏本身根據需求,以及返回的內容來計算點開後的cell應該擁有的高度
5.加載點擊以後的cell內容,同時傳遞點擊的那個section的數據信息
這裏刷新數據是隻刷新點開一個狀況,若是點開多個,數據改變應該是下面,而在cell裏面賦值則不須要了
6.根據須要計算每個section須要的高度(我這裏最後一個有須要)
7.加載每一個section的內容,須要注意,這裏加載的view繼承
UITableViewHeaderFooterView
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
NSArray* objs = [[NSBundle mainBundle] loadNibNamed:@"YunGangScoreTableViewCell" owner:nil options:nil];
YunGangScoreTableViewCell* cell = [objs objectAtIndex: 0];
if (self.scoreDataArray.count>0)
{//確保有數據
YunGangScoreData *data = self.scoreDataArray[section];
cell.data = data;
}
// 單擊的 Recognizer ,收縮分組cell
cell.tag = section;
UITapGestureRecognizer *singleRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(SingleTap1:)];
singleRecognizer.numberOfTapsRequired = 1; //點擊的次數 =1:單擊
[singleRecognizer setNumberOfTouchesRequired:1];//1個手指操做
[cell addGestureRecognizer:singleRecognizer];//添加一個手勢監測;
return cell;
}
同時,爲了適配問題,咱們須要在自定義的view中改變這個view的frame
8.點擊手勢的事件以及處理
9,須要注意的是,每次請求數據,刷新tableview的時候,須要清空_showDic
其餘的內容,就本身根據須要添加修改就能夠了,兩種方法通過測試,第一種展現都沒問題,刷新以後貌似存在混亂,若是須要使用就要好好修改下,第二種方法,測試可使用,不存在什麼大問題,知足需求,下面把效果圖貼上: