UITableView點擊每個Cell,Cell的子內容的收放,uitableviewcell
關於點擊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的資料資訊
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
其他的內容,就自己根據需要添加修改就可以了,兩種方法經過測試,第一種展示都沒問題,重新整理之後貌似存在混亂,如果需要使用就要好好修改下,第二種方法,測試可以使用,不存在什麼大問題,滿足需求,下面把貼上: