關於點擊TableviewCell的子內容收放問題,拿到它的第一個思路就是,
方法一:
運用UITableview本身的代理來處理相應的展開收起:
1.代理:- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
2. 需要聲明一個全局BOOL變量isOpen,記錄當前cell的狀態(展開/收起),聲明一個NSInterge類型selectedIndexRow,記錄選擇的cell的row,切記初始化相應的屬性。
(ps:在網上看到很多文章都是這樣,但是真的用的時候,發現,我們需要另外聲明一個NSIndexPath類型的selectedIndex,或者用到時候自己運用記錄的row生成也可,也許確實是我自己多此一舉)
3.首先,我們需要理清自己需求的邏輯關系,什么時候展開/收起,展開收起時它的高度,個數等等有什么變化------->來進行代理,數據源方法的書寫
下面也是展示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

其他的內容,就自己根據需要添加修改就可以了,兩種方法經過測試,第一種展示都沒問題,刷新之后貌似存在混亂,如果需要使用就要好好修改下,第二種方法,測試可以使用,不存在什么大問題,滿足需求,下面把效果圖貼上:


