天天看點

iOS小經驗:UITableView&UICollectionView設定單元格的預設選中狀态

本文屬 iOS小經驗系列:累積平時看起來簡單,容易忽視的邊邊角角,各路大佬敬請回避。

1. 場景需求

一個表格視圖(或者宮格視圖)中,當一個單元格被選中時設定彩色樣式,選中其它單元格時設定灰色樣式。

2. 一個思路

通過實作選中和非選擇的代理,以在适當的時機進行UI更新操作。

3. UITableView

3.1 通過螢幕點選改變的選中狀态回調給代理

//選中
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
//非選中
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath;           

複制

3.2 代碼設定預設選中狀态 (要等資料加載完成之後再調用)

執行方法的主體:tableview對象

//選中
- (void)selectRowAtIndexPath:(nullable NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UITableViewScrollPosition)scrollPosition;
//非選中
- (void)deselectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated;           

複制

注意的是:

  • 上述代碼強制設定某單元格選中或者不選中那一刻,都不會回調tableview的選中代理方法,也不會發出通知

    UITableViewSelectionDidChangeNotification

  • 之後,通過螢幕點選選中其它cell的時候,可以執行

    - (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath;

    代理方法,你就有機會還原cell的預設樣式。

3.3 補充:代碼設定預設選中狀态

執行方法的主體:cell對象

- (void)setSelected:(BOOL)selected animated:(BOOL)animated;                     // animate between regular and selected state           

複制

注意的是:

  • 這種方法改變cell的選中狀态時,當通過螢幕點選選中其它cell的時候,UITableView并不會執行

    - (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath;

    的非選中代理方法,你也就沒有機會還原cell的預設樣式。

4. UICollectionView

4.1 通過螢幕點選改變的選中狀态回調給代理

//選中
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath;
//非選中
- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath;           

複制

4.2 代碼設定預設選中狀态 (要等資料加載完成之後再調用)

執行方法的主體:UICollectionView對象

//選中
- (void)selectItemAtIndexPath:(nullable NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UICollectionViewScrollPosition)scrollPosition;
//非選中
- (void)deselectItemAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated;           

複制

注意的是:

  • 類似的,上述代碼強制設定某單元格選中或者不選中那一刻,都不會回調選中代理方法,也不會發出通知。
  • 之後,通過螢幕點選選中其它cell的時候,可以執行

    - (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath;

    代理方法,你就有機會還原cell的預設樣式。

4.3 補充:代碼設定選中狀态

執行方法的主體:cell對象

- (void)setSelected:(BOOL)selected;           

複制

注意的是:

  • 類似的,這種方法改變cell的選中狀态時,當螢幕選中其它cell的時候,UITableView并不會執行

    - (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath ;

    代理方法。

5. 比較

比如,下面兩種方案

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:indexPath];
    [cell setSelected:YES];           

複制

上述方案僅僅改變cell的屬性,但當螢幕點選選中其它cell的時候,也不會執行原cell的非選中代理。

[self.collectionView selectItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] animated:YES scrollPosition:UICollectionViewScrollPositionNone];           

複制

上述方案改變了cell的屬性,而且當選中其它cell的時候,會執行非選中代理。

6. 手動執行代理

  • 上述兩張方案的差別在于,設定選中狀态完後,螢幕點選其它cell時,一個執行原cell的

    didDeselect

    方法,一個不執行。
  • 相同點在于,手動設定選中的時候,都是不會執行

    didSelect

    方法的。

如果你真的想在改變選中狀态的時候執行

didSelect

代理,那麼可以手動執行:

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    [mytableview selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:YES scrollPosition:UITableViewScrollPositionTop];
    if ([mytableview.delegate respondsToSelector:@selector(tableView:didSelectRowAtIndexPath:)]) {
        [mytableview.delegate tableView:mytableview didSelectRowAtIndexPath:indexPath];
    }           

複制

本文參與 騰訊雲自媒體分享計劃 ,歡迎熱愛寫作的你一起參與!

本文分享自作者個人站點/部落格

https://www.jianshu.com/u/508ba9810059

複制

如有侵權,請聯系 [email protected] 删除。