最近項目測試出一個隱藏已久的bug,經過多番測試,發現在iOS9下自定義的一個UICollectionViewCell只走一次awakeFromNib。 具體情況是,項目中有一個控制器用到了自定義的UICollectionView,有四組數據,然而有三組自定義的UICollectionViewCel ...
最近項目測試出一個隱藏已久的bug,經過多番測試,發現在iOS9下自定義的一個UICollectionViewCell只走一次awakeFromNib。
具體情況是,項目中有一個控制器用到了自定義的UICollectionView,有四組數據,然而有三組自定義的UICollectionViewCell佈局和子控制項是一樣的,所以只註冊了兩種類型的cell
#import <UIKit/UIKit.h> @interface YimaiDoctorGroupMoreTopicCollectionView : UICollectionView + (instancetype)collectionViewWithObject:(id)object; @end
#define kCollectionviewHeight 96.0 #define kCommonIdentifier @"YimaiDoctorGroupMoreTopicCommonCollectionCell" #define kMyIdentifier @"YimaiDoctorGroupMoreTopicMyCollectionCell" #import "YimaiDoctorGroupMoreTopicCollectionView.h" @implementation YimaiDoctorGroupMoreTopicCollectionView static NSString const *commonIdentifier = @"YimaiDoctorGroupMoreTopicCommonCollectionCell"; static NSString const *myIdentifier = @"YimaiDoctorGroupMoreTopicMyCollectionCell"; + (instancetype)collectionViewWithObject:(id)object { //流水佈局 UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; layout.scrollDirection = UICollectionViewScrollDirectionHorizontal; CGFloat itemHeight = kScreenH - kCollectionviewHeight - kNavigtaionHeight; layout.itemSize = CGSizeMake(kScreenW, itemHeight); layout.minimumLineSpacing = 0; layout.minimumInteritemSpacing = 0; //初始化 YimaiDoctorGroupMoreTopicCollectionView *collection = [[YimaiDoctorGroupMoreTopicCollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout]; //註冊 [collection registerNib:[UINib nibWithNibName:kCommonIdentifier bundle:nil] forCellWithReuseIdentifier:kCommonIdentifier]; [collection registerNib:[UINib nibWithNibName:kMyIdentifier bundle:nil] forCellWithReuseIdentifier:kMyIdentifier]; //分頁 collection.pagingEnabled = YES; //數據源,代理 collection.delegate = object; collection.dataSource = object; // collection.backgroundColor = [UIColor clearColor]; return collection; } @end
在所屬控制器的數據源方法中,初始化和賦值
#pragma mark - UICollectionViewDelegate - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return 4; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { static NSString *identifier; if (indexPath.item < 3) { identifier = @"YimaiDoctorGroupMoreTopicCommonCollectionCell"; YimaiDoctorGroupMoreTopicCommonCollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath]; cell.type = [NSString stringWithFormat:@"%ld",indexPath.item + 1]; FLOG(@"cell ======== %@", cell); return cell; }else{ identifier = @"YimaiDoctorGroupMoreTopicMyCollectionCell"; YimaiDoctorGroupMoreTopicMyCollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath]; cell.type = (int)indexPath.item + 1; return cell; } }
每個自定義的UICollectionViewCell裡面添加了UITableView作為子控制項,並且能上拉載入,下拉刷新,所以有一些初始化
#pragma mark - life cycle - (void)awakeFromNib { [super awakeFromNib]; //設置tableview [self setTableViewAttributes]; self.page = 1; }
當前控制器里頂部還加了資格按鈕,用來點擊可以實現UICollectionView的滑動
上面是核心源碼,看似很正確的實現,最後卻驗證在iOS9下“不能滑動”,即看似下麵這句話不執行
[self.collectionView setContentOffset:CGPointMake(index * kScreenW, 0) animated:NO];
最後通過各種系統版本機型的調試,驗證了,上面的這句setContentOffset沒有問題,有問題的是,iOS9上YimaiDoctorGroupMoreTopicCommonCollectionCell的awakeFromNib方法只執行了一次,而在其他的手機版本下走了三次,所以導致當初註冊的兩種類型的cell,這裡三種看似相同的cell現在都是完全一樣了,數據都一樣。類似於是用的同一個地址,而不是我們認為的,三種長得一樣的cell都擁有自己獨立的地址,所以才導致看著是沒滑動,具體為什麼還在不同的系統版本上有這種情況,查了資料也沒什麼頭緒,有瞭解的伙伴們還請多多指點!!最後只附上解決方法:三種看似相同的cell不復用了,於是有了下麵重用標識符的修改
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { static NSString *identifier; if (indexPath.item < 3) { identifier = [NSString stringWithFormat:@"%@-%ld",@"YimaiDoctorGroupMoreTopicCommonCollectionCell", indexPath.item]; YimaiDoctorGroupMoreTopicCommonCollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath]; cell.type = [NSString stringWithFormat:@"%ld",indexPath.item + 1]; FLOG(@"cell ======== %@", cell); return cell; }else{ identifier = @"YimaiDoctorGroupMoreTopicMyCollectionCell"; YimaiDoctorGroupMoreTopicMyCollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath]; cell.type = (int)indexPath.item + 1; return cell; } }
+ (instancetype)collectionViewWithObject:(id)object { //流水佈局 UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; layout.scrollDirection = UICollectionViewScrollDirectionHorizontal; CGFloat itemHeight = kScreenH - kCollectionviewHeight - kNavigtaionHeight; layout.itemSize = CGSizeMake(kScreenW, itemHeight); layout.minimumLineSpacing = 0; layout.minimumInteritemSpacing = 0; //初始化 YimaiDoctorGroupMoreTopicCollectionView *collection = [[YimaiDoctorGroupMoreTopicCollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout]; //註冊 //解決ios9下 自定義的一個UICollectionViewCell只走一次awakeFromNib for (int i = 0; i < 3; i++) { [collection registerNib:[UINib nibWithNibName:kCommonIdentifier bundle:nil] forCellWithReuseIdentifier:[NSString stringWithFormat:@"%@-%d", @"YimaiDoctorGroupMoreTopicCommonCollectionCell", i]]; } // [collection registerNib:[UINib nibWithNibName:kCommonIdentifier bundle:nil] forCellWithReuseIdentifier:kCommonIdentifier]; [collection registerNib:[UINib nibWithNibName:kMyIdentifier bundle:nil] forCellWithReuseIdentifier:kMyIdentifier]; //分頁 collection.pagingEnabled = YES; //數據源,代理 collection.delegate = object; collection.dataSource = object; // collection.backgroundColor = [UIColor clearColor]; return collection; }