简体   繁体   English

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

[英]How to set width of UICollectionView on rotation with auto layout programmatically swift

I've set up a collection view with self sizing cells using auto layout. 我已经使用自动布局设置了具有自定义尺寸单元的集合视图。 However, when I rotate the device the collection view still uses the portrait width and gets cut off. 但是,当我旋转设备时,集合视图仍然使用纵向宽度并被切除。 I am using flow layout and not the sizeForItemAt method. 我正在使用流布局,而不是sizeForItemAt方法。

Here is my main view controller: 这是我的主视图控制器:

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] = []

Also, here is one of my cells: 另外,这是我的一个牢房:

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
  }
}

I already had tried using Auto Layout as Sh_Khan's suggested. 我已经尝试过按照Sh_Khan的建议使用“自动布局”。 I updated the code above. 我更新了上面的代码。 However, when I rotate, the collection view get's updated but the cells still stay the size of a portrait width device. 但是,当我旋转时,会更新集合视图,但是单元格仍然保持纵向宽度设备的大小。 I added a screenshot. 我添加了屏幕截图。

风景截图 I removed the content with red marking 我删除了带有红色标记的内容

Could anyone point me in the right direction seeing as how invalidateLayout() doesn't work on flow layout. 谁能指出我正确的方向,因为invalidateLayout()在流布局上不起作用。

Thanks in advance 提前致谢

The problem is that giving the collection a frame when creating makes it keep it even after rotation , you can try to use autoLayout 问题是在创建集合时给集合一个框架使其即使旋转后也能保持它,您可以尝试使用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

You can achieve this without using auto-layout as well, The view controller tells you when its view gets new frame (when rotated eg) through viewWillLayoutSubviews or viewDidLayoutSubviews which is a good place to set all your frame/position related properties. 您也可以不使用自动布局来实现这一点,视图控制器通过viewWillLayoutSubviewsviewDidLayoutSubviews告诉您其视图何时获得新帧(例如旋转时),这是设置所有与帧/位置相关的属性的好地方。

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

    // Set frames of other views that may have change 
}

And for the cell there is override layoutSubviews() 对于该单元格有override layoutSubviews()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM