Reputation: 65
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.
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. 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.
Thanks in advance
Upvotes: 0
Views: 991
Reputation: 452
You can achieve this without using auto-layout as well, The view controller tells you when its view gets new frame (when rotated e.g.) through viewWillLayoutSubviews
or viewDidLayoutSubviews
which is a good place to set all your frame/position related properties.
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()
Upvotes: 1
Reputation: 100523
The problem is that giving the collection a frame when creating makes it keep it even after rotation , you can try to use 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
Upvotes: 2