簡體   English   中英

將 UICollectionLayoutListConfiguration 與情節提要一起使用

[英]Using UICollectionLayoutListConfiguration with storyboards

您可以將 iOS 14 中新的UICollectionLayoutListConfiguration API 與故事板中的集合視圖一起使用嗎?

我在情節UICollectionViewController中有一個UICollectionViewController ,我使用下面的自定義列表布局對其進行配置:

var config = UICollectionLayoutListConfiguration(appearance: .plain)
let layout = UICollectionViewCompositionalLayout.list(using: config)
collectionView.setCollectionViewLayout(layout, animated: false)
collectionView.dataSource = dataSource

(在故事板集合視圖中只能使用流程或自定義布局設置)

這使用標准的可區分數據源:

return UICollectionViewDiffableDataSource(collectionView: collectionView) { (collectionView, indexPath, item) in
    guard let cell = collectionView.dequeueReusableCell(
        withReuseIdentifier: "SomeCell",
        for: indexPath
    ) as? SomeCell else {
        fatalError("Couldn't dequeue cell \(reuseIdentifier)")
    }

    cell.setItem(item)
    return cell
}

然而,我得到了一些非常奇怪的行為,例如旋轉屏幕時IBOutlets為零,盡管在旋轉之前一切正常。

我沒有找到調試這里發生的事情的好方法,堆棧跟蹤看起來是正確的,並且單元的類已初始化,並且它正在主線程上運行。

奇怪的 nil IBOutlot

我已經復制了您代碼的每一步,最終結果符合我的預期。

在此處輸入圖片說明

這是縱向模式下的最終結果

在此處輸入圖片說明

這是橫向模式的最終結果

我打算做的是在集合視圖中顯示數字列表,以下是必要的文件供您參考:

UICollectionViewController

import UIKit

private let reuseIdentifier = "SomeCell"

enum Section {
  case main
}

class SampleCollectionViewController: UICollectionViewController {
  
  var dataSource: UICollectionViewDiffableDataSource<Section, Int>!
  
  override func viewDidLoad() {
    super.viewDidLoad()
    
    self.collectionView.setCollectionViewLayout(getLayout(), animated: false)
    configureDataSource()
  }
  
  func getLayout() -> UICollectionViewCompositionalLayout {
    
    let config = UICollectionLayoutListConfiguration(appearance: .plain)
    let layout = UICollectionViewCompositionalLayout.list(using: config)
    return layout
  }
  
  func configureDataSource() {
    
    dataSource = UICollectionViewDiffableDataSource<Section, Int>(collectionView: self.collectionView, cellProvider: { (collectionView, indexPath, number) -> UICollectionViewListCell? in
      
      guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as? SomeCell else {
        fatalError("Cannot create cell")
      }
      
      cell.label.text = number.description
      return cell
    })
    
    var initialSnapshot = NSDiffableDataSourceSnapshot<Section, Int>()
    initialSnapshot.appendSections([.main])
    initialSnapshot.appendItems(Array(1...100), toSection: .main)
    
    dataSource.apply(initialSnapshot, animatingDifferences: false)
  }
}

UICollectionViewListCell

import UIKit

class SomeCell: UICollectionViewListCell {
    
  @IBOutlet weak var label: UILabel!
  
  override func updateConstraints() {
    super.updateConstraints()
    
    label.textColor = .blue
  }
}

故事板設置: 在此處輸入圖片說明 在此處輸入圖片說明 在此處輸入圖片說明

我按照標准步驟做了所有這些,這里沒什么特別的

重要提示:在這里我找到了你實現不同的一個潛在的地方是,你已經dequeued細胞withReuseIdentifier"SomeCell"但細胞類,你已經證明拋出的錯誤是TextCell如果你能提供在同更多的細節那么這將是有益的縮小您面臨的錯誤。

這是簡化的演示。 大部分基於以某種方式復制了您的代碼。

使用 Xcode 12 / iOS 14 測試

演示

struct SomeItem: Hashable {
    let id = UUID()
    var value: String
}

class SomeCell: UICollectionViewCell {
    @IBOutlet weak var label: UILabel!
    var item: SomeItem!
    
    func setItem(_ item: SomeItem) {
        self.item = item
        label.text = item.value
    }
    
    override func awakeFromNib() { // called when all outlets connected
        super.awakeFromNib()
        label.textColor = .blue
    }
}

class ViewController: UICollectionViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let config = UICollectionLayoutListConfiguration(appearance: .plain)
        let layout = UICollectionViewCompositionalLayout.list(using: config)
        collectionView.setCollectionViewLayout(layout, animated: false)
        collectionView.dataSource = dataSource
    }

    lazy var dataSource = {
        UICollectionViewDiffableDataSource<Int, SomeItem>(collectionView: self.collectionView) { (collectionView, indexPath, item) in
             guard let cell = collectionView.dequeueReusableCell(
                  withReuseIdentifier: "SomeCell",
                  for: indexPath
             ) as? SomeCell else {
                  fatalError("Couldn't dequeue cell")
             }

             cell.setItem(item)
             return cell
        }
    }()
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        var snapshot = NSDiffableDataSourceSnapshot<Int, SomeItem>()
        snapshot.appendSections([0])
        snapshot.appendItems([SomeItem(value: "Jan"), SomeItem(value: "Fab"), SomeItem(value: "Mar")])
        dataSource.apply(snapshot)
    }
}

故事板沒有什么特別之處——只為視圖控制器和單元格應用了自定義類(為簡單起見,標簽居中)並制作了自定義集合視圖布局:

演示2

演示3

演示4

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM