如何使用自动布局以编程方式快速设置旋转时 UICollectionView 的宽度

Posted

技术标签:

【中文标题】如何使用自动布局以编程方式快速设置旋转时 UICollectionView 的宽度【英文标题】:How to set width of UICollectionView on rotation with auto layout programmatically swift 【发布时间】:2018-03-15 18:14:23 【问题描述】:

我已经使用自动布局设置了一个带有自我调整大小的单元格的集合视图。但是,当我旋转设备时,集合视图仍然使用纵向宽度并被截断。我使用的是流布局而不是 sizeForItemAt 方法。

这是我的主视图控制器:

import UIKit

class HomeController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate 

  override func viewDidLoad() 
    super.viewDidLoad()
  

  override func viewWillAppear(_ animated: Bool) 
    super.viewWillAppear(animated)

    let layout = UICollectionViewFlowLayout()
    layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize
    layout.minimumLineSpacing = 0
    layout.scrollDirection = .vertical

    let homeCollectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
    homeCollectionView.dataSource = self
    homeCollectionView.delegate = self
    homeCollectionView.backgroundColor = .orange

    homeCollectionView.register(CellTypeOne.self, forCellWithReuseIdentifier: "CellType1")

    self.view.addSubview(homeCollectionView)
    homeCollectionView.translatesAutoresizingMaskIntoConstraints = false
homeCollectionView.leadingAnchor

.constraint(equalTo: self.view.leadingAnchor).isActive = true
    homeCollectionView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
    homeCollectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
    homeCollectionView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true

  

  func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
    return contents.count
  

  func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    // code for specific type of cells
  

  let contents: [ContentType] = []

另外,这是我的一个细胞:

import UIKit

class CellType1: UICollectionViewCell 

  override init(frame: CGRect) 
    super.init(frame: frame)
    setupViews()
  

  required init?(coder aDecoder: NSCoder) 
    fatalError("init(coder:) has not been implemented")
  

  var content: Content? 
    didSet 
      sectionTextView.text = content?.sectionView
    
  

  let sectionTextView: UITextView = 
    let textView = UITextView()
    textView.contentInset = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
//    textView.backgroundColor = .orange
    textView.translatesAutoresizingMaskIntoConstraints = false
    textView.textContainerInset = UIEdgeInsetsMake(10, 0, 20, 0)
    textView.text = "This is a Section text"
    textView.font = UIFont.systemFont(ofSize: 20, weight: .heavy)
    textView.textColor = UIColor(red: 76/255, green: 76/255, blue: 77/255, alpha: 1.0)
    textView.isEditable = false
    textView.isScrollEnabled = false
    return textView
  ()

  func setupViews() 
    addSubview(sectionTextView)

    let widthAnchorConstraint = sectionTextView.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.size.width - 16)
    widthAnchorConstraint.identifier = "sectionTextView Width Anchor Constraint"
    widthAnchorConstraint.priority = UILayoutPriority(rawValue: 1000)
    widthAnchorConstraint.isActive = true

    let topAnchorConstraint = sectionTextView.topAnchor.constraint(equalTo: topAnchor)
    topAnchorConstraint.identifier = "sectionTextView Top Anchor Constraint"
    topAnchorConstraint.isActive = true

    let leftAnchorConstraint = sectionTextView.leftAnchor.constraint(equalTo: leftAnchor)
    leftAnchorConstraint.identifier = "sectionTextView Left Anchor Constraint"
    leftAnchorConstraint.isActive = true

    let rightAnchorConstraint = sectionTextView.rightAnchor.constraint(equalTo: rightAnchor)
    rightAnchorConstraint.identifier = "sectionTextView Right Anchor Constraint"
    rightAnchorConstraint.priority = UILayoutPriority(rawValue: 999)
    rightAnchorConstraint.isActive = true

    let bottomAnchorConstraint = sectionTextView.bottomAnchor.constraint(equalTo: bottomAnchor)
    bottomAnchorConstraint.identifier = "sectionTextView Bottom Anchor Constraint"
    bottomAnchorConstraint.isActive = true
  

我已经按照 Sh_Khan 的建议尝试过使用自动布局。我更新了上面的代码。但是,当我旋转时,集合视图会更新,但单元格仍保持纵向宽度设备的大小。我添加了一个屏幕截图。

我删除了带有红色标记的内容

谁能指出我正确的方向,看看 invalidateLayout() 如何在流布局上不起作用。

提前致谢

【问题讨论】:

利用尺寸等级。在那里您可以为所有尺寸设置不同的布局。 @SHISHIRRAMIN,我无法让它工作。我该怎么做呢。我在这里试过:***.com/questions/49459702/… 【参考方案1】:

问题是在创建时给集合一个框架使它即使在旋转后也保持它,你可以尝试使用 autoLayout

    self.view.addSubview(homeCollectionView)
    homeCollectionView.translatesAutoresizingMaskIntoConstraints = false 
    homeCollectionView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
    homeCollectionView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
    homeCollectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
    homeCollectionView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true

【讨论】:

我用我的新发现更新了我的问题。仍然无法正常工作。【参考方案2】:

您也可以在不使用自动布局的情况下实现此目的,视图控制器会通过viewWillLayoutSubviewsviewDidLayoutSubviews 告诉您其视图何时获得新框架(例如旋转时),这是设置所有框架的好地方/位置相关的属性。

override func viewDidLayoutSubviews() 
    super.viewDidLayoutSubviews()
    homeCollectionView.frame = view.frame

    // Set frames of other views that may have change 

对于单元格有override layoutSubviews()

【讨论】:

这不起作用。当我实现这段代码时,集合视图向左对齐,仍然使用纵向宽度,屏幕的其余部分是空白的。 嘿,试试 viewDidLayoutSubviews() 还是一样的效果。全宽集合视图。但是单元格没有更新到新的宽度。 他们有一个非常相似的方法叫做 layoutSubviews() 你也应该重写 仍然没有效果。我将 layoutSubviews() 方法添加到单元格类并尝试更新约束,因为我想继续使用自动布局。没有运气,当我尝试使用 frame.width 并更新它时,仍然没有运气..

以上是关于如何使用自动布局以编程方式快速设置旋转时 UICollectionView 的宽度的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式使用自动布局以编程方式添加 UIview?

如何以编程方式自动旋转UIScrollView和UIImageView?

如何使用自动布局以编程方式创建 UITableView?

自动布局比例间距

可以在旋转时自动调整视图的大小以尽可能大吗?

调整大小后使用自动布局以编程方式居中 UIImageVIew