iOS9下UICollectionViewCell的awakeFromNib問題

来源:https://www.cnblogs.com/jingxin1992/archive/2018/05/09/9013298.html
-Advertisement-
Play Games

最近項目測試出一個隱藏已久的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;
}

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 上班坐下來沒多久,接同事電話說有兩台mysql伺服器無法訪問,其中這兩台伺服器是mycat伺服器+MySQL伺服器,具體處理過程如下: 一、錯誤信息 錯誤信息01: 錯誤信息02: 錯誤信息03: 二、錯誤原因 1、針對錯誤信息01,基本可以斷定是由於伺服器jvm設置不當,導致記憶體溢出。 2、針對錯 ...
  • 雙擊打開後加上 ;-m 然後以管理員方式 打開 SQLSERVER 2008 就可以已window身份登錄 不過還沒有完 右鍵 屬性 =》安全性 更改為 sql server 和 window身份驗證模式 沒有sql server登陸賬號的話創建一個 然後把-m去掉就可以用帳號登錄了 ...
  • MariaDB/MySQL備份恢復系列: 備份和恢復(一):mysqldump工具用法詳述 備份和恢復(二):導入、導出表數據 備份和恢復(三):xtrabackup用法和原理詳述 本文目錄: 1.安裝xtrabackup 2.備份鎖 3.xtrabackup備份原理說明 3.1 備份過程(back ...
  • MySQL元數據 Meta Data,一般是結構化數據(如存儲在資料庫里的數據,欄位長度、類型、預設值等等)。Meta Data就是描述數據的數據,在MySQL中描述有哪些資料庫、哪些表、表有多少欄位、類型。 MySQL元數據信息 查詢結果信息,SELECT、UPDATE或DELETE語句影響的行數 ...
  • 當實際項目上線到生產環境中,難以避免一些意外情況,如數據丟失、伺服器停機等。對於系統的搜索服務來說,當遇到停機的情況意味著在停機這段時間內,用戶都不能通過搜索的相關功能進行訪問數據,停機意味著將這一段時間內的數據服務完全停止。如果項目是互聯網項目依賴於用戶數量,這將嚴重影響用戶訪問和用戶的產品體驗。 ...
  • 本文主要總結並記錄一下簡單且常用的mysql 在cmd 視窗中操作的基本命令 命令停止mysql 資料庫服務 1.(cmd)命令行 2.手動: 1. 使用快捷鍵 ctr+alt+delete =》2. 啟動任務管理器=》3. 進入服務 =》4.找到mysql 將其啟動/關閉 3.登錄/退出mysql ...
  • 設計模式六大基本原則 1.單一職責原則 英文:Single Responsibility Principles,縮寫SRP 定義:就一個類而言,應該僅有一個引起它變化的原因。 理解:例如兩個完全不一樣的功能就不應該放在一個類中。一個類總應該是一組相關性很高的函數,數據的封裝。 對應一個類,不求功能面 ...
  • 最近用到JS和OC原生方法調用的問題,查了許多資料都語焉不詳,自己記錄一下吧,如果有誤歡迎聯繫我指出。 JS中調用OC方法有三種方式: 先上OC代碼 // 設置javaScriptContext上下文 self.jsContext = [self.webView valueForKeyPath:@" ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...