【问题标题】:How to auto-resize UICollectionView when device rotates?设备旋转时如何自动调整 UICollectionView 的大小?
【发布时间】:2016-12-02 08:21:00
【问题描述】:

每次我旋转设备时,我都在尝试调整我的 collectionViewCells 的大小,但我不知道该怎么做。这是我的问题和我的代码。它在 Swift 3 和 Xcode 8 中。

这是我们加载的第一个屏幕

当我旋转设备单元格时仍然具有相同的宽高

另一方面,如果我在设备旋转(横向)时加载 firstScreen(HomePage),然后我再次将设备旋转到纵向,单元格会溢出,所以我看不到它们的侧面。因为宽度仍然与横向宽度相同。

    // MARK: UICollectionViewDataSource

override func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 1
}

override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return allNews.count
}

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath) as! HomeCollectionViewCell

    // Configure the cell
    cell.imageView.image = allNews[indexPath.row].newsPic
    cell.textView.text = allNews[indexPath.row].newsTitle
    return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let height = (view.frame.width - 32) * 9 / 16
    return CGSize(width: view.frame.width, height: height + 94)
}


func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return 0
}


// MARK: Orientation Changes ( reload the CollectionLayout )
override func didRotate(from fromInterfaceOrientation: UIInterfaceOrientation) {

}

最后我没有在 Main.storyboard 中使用自动布局。这是我在 HomeCollectionViewCell 类中的 setupViews() 方法

    private func setupViews() {
    addSubview(imageView)
    addSubview(textView)
    addSubview(separatorView)
    addSubview(dateView)

    addConstraintsWithFormat(format: "H:|-16-[v0]-16-|", views: imageView)
    addConstraintsWithFormat(format: "V:|-16-[v0]-8-[v1(40)]-2-[v2(20)]-8-|", views: imageView, textView, dateView)

    addConstraintsWithFormat(format: "H:|-16-[v0]-16-|", views: textView)
    addConstraintsWithFormat(format: "H:|-16-[v0]-16-|", views: dateView)

    addConstraintsWithFormat(format: "H:|[v0]|", views: separatorView)
    addConstraintsWithFormat(format: "V:[v0(1)]|", views: separatorView)
}

问候。

已解决!:我使用了这个方法而不是 override func didRotate(from fromInterfaceOrientation: UIInterfaceOrientation) {}

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)
    collectionView?.collectionViewLayout.invalidateLayout()
}

【问题讨论】:

  • 您使用的是故事板或笔尖的自动布局吗?
  • 感谢您的解决方案,这对我有用——swift 3 xcode 8.3.1 部署目标 iOS 10.0

标签: swift mobile xcode8


【解决方案1】:

查看我的解决方案。

let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
layout.itemSize = CGSize(width: 100, height: 100)
let controller = UICollectionViewController(collectionViewLayout: layout))

在 iOS8+ 中,该函数不再是 override func didRotate(from fromInterfaceOrientation: UIInterfaceOrientation) {}

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)
        if let layout =  self.collectionView?.collectionViewLayout as? UICollectionViewFlowLayout{
            layout.itemSize = CGSize(width: 200, height: 200)
        }
    }

这对我有用。试试看。

【讨论】:

  • 谢谢我在你的帮助下解决了这个问题。唯一的区别是我没有在 viewWillTransitition 方法中使用特定的 itemSize 宽度/高度大小。因为 invalidateLayout() 方法为我们处理了这些。
  • @UnalCelik 是的。但有时,大小差异很大,我们必须调整它的大小。
【解决方案2】:

您应该使用 self.view.bounds 而不是 self.view.frame,因为当设备旋转的框架在纵向和横向中保持不变时,只会更改绑定。

【讨论】:

    【解决方案3】:

    因为我在集合视图中有固定的行数,所以我必须在设备旋转时调整单元格大小。我希望这会有所帮助:

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        guard let flowLayout = collectionView?.collectionViewLayout as? UICollectionViewFlowLayout else {
            return
        }
    
        if UIInterfaceOrientationIsLandscape(UIApplication.shared.statusBarOrientation) {
            //here you can do the logic for the cell size if phone is in landscape
    
        } else {
            //logic if not landscape
        }
        let cellSize =  CGSize(width: (size.width - CGFloat(row ))/CGFloat(row)  , height: 90)
        flowLayout.itemSize = cellSize
        flowLayout.invalidateLayout()
    }
    

    * row 是我的行数,你可以根据自己的情况更改。

    【讨论】:

      猜你喜欢
      • 2012-01-06
      • 2016-03-12
      • 2017-03-19
      • 2011-12-29
      • 1970-01-01
      • 1970-01-01
      • 2018-05-02
      • 1970-01-01
      • 2018-11-11
      相关资源
      最近更新 更多