應(yīng)用場(chǎng)景
在 UITableViewCell 中嵌入一個(gè)播放器
當(dāng)某一個(gè) Cell 被移出屏幕的時(shí)候,對(duì)改 Cell 進(jìn)行處理,包括暫?;蛲5舨シ牌?或者其他的操作.
基本思路
關(guān)于判斷 UITableViewCell 是否移出屏幕,可以先了解怎么判斷 Cell 在屏幕中
- UITableView 有兩個(gè)關(guān)于 Cell可用的屬性
@property (nonatomic, readonly) NSArray<__kindof UITableViewCell *> *visibleCells;
-
@property (nonatomic, readonly, nullable) NSArray<NSIndexPath *> *indexPathsForVisibleRows;
使用兩個(gè)屬性可以獲取到 UITableView 的可視范圍內(nèi)的相關(guān)屬性,一 個(gè)是 Cell 的數(shù)組還有一個(gè)是 NSIndexPath 數(shù)組.不過(guò)在實(shí)際操作中發(fā)現(xiàn)使用這兩個(gè)屬性來(lái)做為判斷依據(jù)不是非常準(zhǔn)確,所以放棄使用.
- 第二個(gè)就是從 frame 相關(guān)信息入手,對(duì)于一個(gè) Cell 來(lái)說(shuō),大概的關(guān)系是UIView(即 VC 視圖) -> UITableView ->UITableViewCell, 就是說(shuō)先將 Cell 在 UITableView 中的位置找到,然后通過(guò)轉(zhuǎn)換函數(shù)轉(zhuǎn)換成在 VC 視圖的位置,這種方法是比較準(zhǔn)確,暴力的方法,所以使用該方法來(lái)處理我們需要的業(yè)務(wù)邏輯.即
CGRect rectInTableView = [_tableView rectForRowAtIndexPath: self.operatedCellIndexPath];
CGRect rectInSuperview = [_tableView convertRect:rectInTableView toView:[_tableView superview]];
關(guān)于在 UICollectionView中的實(shí)現(xiàn)方式類似,不過(guò)由于 UICollectionView 中并沒(méi)有 rectForRowAtIndexPath: 這種方法,所以使用
CGRect cellRect = [_collectionView convertRect:self.currentPlayingCell.frame toView:_collectionView];
CGRect rectInSuperview = [_collectionView convertRect:cellRect toView:self.view];
這種方式,思路是一致的.
具體實(shí)現(xiàn)
到這里,我們的需求基本上已經(jīng)完成了,剩下需要做的就是記錄下我們需要操作的 Cell, 因?yàn)槲覀兣袛?Cell 移出屏幕,肯定是對(duì)已經(jīng)操作過(guò)的 Cell 進(jìn)行下一步處理,比如視頻的暫?;蛘咄V共シ诺鹊?這樣可以寫個(gè) Block,在加載 Cell 的時(shí)候記錄下我們操作的 Cell,本文就是在播放視頻的時(shí)候,調(diào)用 block 記錄下當(dāng)前的 Cell,并且停止正在播放的 Cell 中的 VideoPlayer.
WEAKSELF
cell.startPlayVideoAction = ^(){
STRONGSELF
// WAKSELF 和 STRONGSELF 是我寫的宏,就是循環(huán)引用的那個(gè)東西
// 這個(gè)地方可以對(duì)上一次記錄的 Cell 和 IndexPath 進(jìn)行處理,比如我就可以把正在播放的視頻停掉,類似這樣
// 記錄 當(dāng)前被點(diǎn)擊 cell 的位置和 indexPath
strongSelf.operatedCellIndexPath = indexPath;
strongSelf.currentPlayingCell = [strongSelf.tableView cellForRowAtIndexPath: indexPath];
};
最后一步就是在 UITableView 或者 UICollectionView 滑動(dòng)的時(shí)候進(jìn)行監(jiān)聽了
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
// 這里我記錄了 Cell 的 IndexPath 和 Cell
if ( self.operatedCellIndexPath != nil ) {
CGRect rectInTableView = [self.tableView rectForRowAtIndexPath: self.operatedCellIndexPath];
CGRect rectInSuperview = [self.tableView convertRect:rectInTableView toView:[self.tableView superview]];
if ( rectInSuperview.origin.y > SCREEN_HEIGHT || rectInSuperview.origin.y + rectInSuperview.size.height < 0 ) {
// 對(duì)已經(jīng)移出屏幕的 Cell 做相應(yīng)的處理
}
}
}
本文主要以 UITableView 為例子,進(jìn)行總結(jié),不過(guò) UICollectionView 大概的思路是一直的,不過(guò)是在獲取 Cell 的 frame 的時(shí)候的方式不一樣罷了.