簡體   English   中英

UICollectionViewCell-不同大小類的不同布局

[英]UICollectionViewCell - different layout for different size classes

我有一個帶有一個圖像和一個標簽的簡單UICollectionViewCell 在常規-常規尺寸類中,我希望圖像位於頂部,標簽位於其下方。 這是Xcode的預覽選項卡中的樣子:

在此處輸入圖片說明

在任何其他尺寸類別中,我都希望圖像在左側,標簽在右側:

在此處輸入圖片說明

我以這種方式設置約束:

ImageView具有以下約束:

  • 任何人的主要和主要約束
  • 任何寬度的固定寬度和高度

標簽具有以下約束:

  • 跟蹤約束到Superview-任意
  • ImageView的最大約束-僅適用於Regular-Regular
  • Superview的主要約束-僅適用於Regular-Regular
  • Superview的主要限制-任意,但不包括常規-常規
  • 對ImageView的主要約束-任意,但不適用於常規-常規

我還實現了基於當前特征收集返回不同單元格大小的方法:

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
    if (traitCollection.horizontalSizeClass == .Regular) {
      return CGSizeMake(240, 194)
    }
    else {
      return CGSizeMake(340, 128)
    }
  }

該單元格在預覽中看起來很好,並且當我在iPhone上運行它時,所有功能都可以正常工作(例如Compact-Regular)。 但是,當我在iPad上運行時,自動布局會中斷:

在此處輸入圖片說明

當然,我在調試控制台中收到一堆警告:無法同時滿足約束。

因此,我想問題是-為不同大小的類設置單元的正確方法是什么?

我用一個演示項目創建了一個github倉庫

謝謝!

您想要做的是像您一樣禁用Regular-Regular大小類的那些約束,還可以將其優先級更改為<1000(即不是必需的)。 這樣,它將對特定大小的類使用更高優先級的約束。

在此處輸入圖片說明

這可能不是最優雅的解決方案,但是我過去的嘗試使Autolayout尺寸類更加痛苦,我發現最好的解決方案是:

  1. 每個尺寸等級都有一個單獨的筆尖,然后根據需要布局每個尺寸的視圖。
  2. 每個尺寸類都有單獨的CollectionViewFlowLayouts ,然后在尺寸改變時在它們之間過渡。

按照這種模式,像元大小將由collectionViewFlowlayout而不是sizeForItem... ,您將對其他參數有更多控制,例如sectionInsetminimumLineSpacing等,這些參數在更改集合視圖中的大小類時通常需要進行更改。

以下是對我有用的代碼更改:

  let cellIdentifierCompact = "CustomCellCompact"
  let cellIdentifierRegular = "CustomCellReg"

  lazy var compactLayout: UICollectionViewFlowLayout = {
    let layout = UICollectionViewFlowLayout()
    layout.itemSize = CGSizeMake(240, 194)
    return layout
  }()

lazy var regLayout: UICollectionViewFlowLayout = {
    let layout = UICollectionViewFlowLayout()
    layout.itemSize = CGSizeMake(320, 128)
    return layout
  }()

override func viewDidLoad() {
    super.viewDidLoad()

    let customCellNib = UINib(nibName: cellIdentifierCompact, bundle: nil)
    self.collectionView.registerNib(customCellNib, forCellWithReuseIdentifier: cellIdentifierCompact)

    let customCellNibReg = UINib(nibName: cellIdentifierRegular, bundle: nil)
    self.collectionView.registerNib(customCellNibReg, forCellWithReuseIdentifier: cellIdentifierRegular)
    self.configureLayoutForSize()
  }


func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cellId = self.collectionView.collectionViewLayout == self.regLayout ? cellIdentifierRegular : cellIdentifierCompact
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(cellId, forIndexPath: indexPath)
    return cell
  }

  func configureLayoutForSize(){
    switch self.traitCollection.horizontalSizeClass{
    case UIUserInterfaceSizeClass.Regular:
      self.collectionView.setCollectionViewLayout(self.regLayout, animated: false)
    case .Compact, .Unspecified:
      self.collectionView.setCollectionViewLayout(self.compactLayout, animated: false)
    }
  }

  override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    self.configureLayoutForSize()
    self.collectionView.reloadData()
  }

暫無
暫無

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

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