ios - 基于约束的 collectionView 的不同单元格大小

标签 ios swift uicollectionview

我创建了一个 collectionView,其中我有 3 个单元格,第一个单元格必须填充第一行,第三个单元格应该填充第二行但是我似乎无法弄清楚如何做到这一点,因为每次我尝试在sizeForItemAt 我知道 collectionView 框架是 (0, 0, 0, 0)

这是我目前的情况

class FlowLayout: UICollectionViewFlowLayout {

    var numberOfCells: Int!

    override init() {
        super.init()
        setupLayout()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setupLayout()
    }

    func setupLayout() {
        minimumInteritemSpacing = 1
        minimumLineSpacing = 1

    }

    override var itemSize: CGSize {
        set {

        }
        get {
            let numberOfColumns: CGFloat = 2

            let itemWidth = (self.collectionView!.frame.width - (numberOfColumns - 1)) / numberOfColumns
            let itemHeight = self.collectionView!.frame.height / 2


            return CGSize(width: itemWidth, height: itemHeight)
        }
    }


}

说明我想要什么

在我的 View 中设置collectionView

func createCollectionView() {
    let layout = FlowLayout()
    layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
    layout.numberOfCells = 2



    collectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
    collectionView.dataSource = self
    collectionView.delegate = self
    collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "Cell")
    collectionView.backgroundColor = UIColor.white
    collectionView.isScrollEnabled = false
    self.topWrapperView.addSubview(collectionView)


    collectionView.snp.makeConstraints { (make) -> Void in

        make.left.equalTo(topWrapperView).offset(0)
        make.top.equalTo(topWrapperView).offset(0)
        make.bottom.equalTo(topWrapperView).offset(0)
        make.right.equalTo(topWrapperView).offset(0)
    }
}

enter image description here

最佳答案

我遇到了类似的情况,只是它是第一个单元格,我希望第一行有 2 个单元格,之后每行 3 个。将其用于图像 Collection View 中的主要个人资料图片和个人简介。我使用带有默认 UICollectionViewDelegateFlowLayout 的 sizeForItemAtIndexPath 成功地实现了它。 以下是适合您情况的内容:

 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

let insets = collectionView.contentInset
let collectionViewWidth = collectionView.frame.width - (insets.left + insets.right + 1)
let collectionViewHeight = collectionView.frame.height - (insets.top + insets.bottom)

  switch indexPath.row {
   case 0, 1:

   return CGSize(width: collectionViewWidth / 2, height: collectionViewHeight / 2)

    default:
    return CGSize(width: collectionViewWidth, height: collectionViewHeight / 2)
  }
}

您可以更改除以高度的值以获得所需的高度。

这是我针对我的情况写的,我想我会把它贴出来,因为它可以帮助你或任何阅读它的人。如果您希望它随着旋转而改变,请使用 viewWillTransition 并使用 didSet 监听器设置 bool 标志:

 var isPortraitOrientation: Bool = true {
   didSet {
 if oldValue != isPortraitOrientation {
    collectionView?.collectionViewLayout.invalidateLayout()
     }
   }
} 

 override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
   super.viewWillTransition(to: size, with: coordinator)
  isPortraitOrientation = (size.width - size.height) <= 0 ? true : false
}


 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

    let insets = collectionView.contentInset
    let collectionViewWidth = collectionView.frame.width - (insets.left + insets.right + 1)
    let collectionViewHeight = collectionView.frame.height - (insets.top + insets.bottom)

    switch indexPath.row {
    case 0:

        if textViewSelected {
            return isPortraitOrientation ? CGSize(width: collectionViewWidth, height: collectionViewHeight / 2) : CGSize(width: collectionViewWidth, height: collectionViewWidth / 3)
        } else {
            return isPortraitOrientation ? CGSize(width: collectionViewWidth / 2, height: collectionViewWidth / 2) : CGSize(width: collectionViewWidth / 2, height: collectionViewHeight / 1.5)
        }
    case 1:
        return isPortraitOrientation ? CGSize(width: collectionViewWidth / 2, height: collectionViewWidth / 2) : CGSize(width: collectionViewWidth / 2, height: collectionViewHeight / 1.5)

    default:
        return isPortraitOrientation ? CGSize(width: collectionViewWidth / 3, height: collectionViewWidth / 3) : CGSize(width: collectionViewWidth / 5, height: collectionViewWidth / 5)
    }
}

编辑:

根据您的附加代码,不要为 collectionView 框架执行 CGRect.zero,而是使用 topWrapperView.bounds。

关于ios - 基于约束的 collectionView 的不同单元格大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40330322/

相关文章:

javascript - 在 Ios 设备上强制播放音频

ios - Xcode 中的代码签名 "Debug"或 "Release"有什么意义?

ios - 在 WatchKit 2.0 上更改 WKInterfacePicker 的颜色

ios - 如何在 MSMessage 中嵌入 URL?

ios - 删除 UITableView 行时删除通知(Swift)

ios - 如何在 Swift 4 中向数组追加或添加多个项目

ios - Google Maps sdk for iOS 中折线的轮廓

ios - UICollectionViewLayout sectionInset 不工作

ios - 停用并激活特定的UILocalNotification

ios - 与 UICollectionView 单元格一起滑动 View