UICollectionView full width and height problem - ios

UICollectionView width is not full width, One cell per row
UICollectionView
private func setCollectionView() {
let layout = UICollectionViewFlowLayout()
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 0
layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
layout.scrollDirection = .horizontal
collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.showsHorizontalScrollIndicator = false
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.isPagingEnabled = true
collectionView.register(ImageCollectionViewCell.self, forCellWithReuseIdentifier: "cell")
}
UICollectionView -> Constraint
NSLayoutConstraint.activate([
view.leadingAnchor.constraint(equalTo: collectionView.leadingAnchor),
view.trailingAnchor.constraint(equalTo: collectionView.trailingAnchor),
view.topAnchor.constraint(equalTo: collectionView.topAnchor),
view.bottomAnchor.constraint(equalTo: collectionView.bottomAnchor)
])
UIColletionViewCellSize
By adding UICollectionViewFlowLayoutDelegate
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.frame.width, height: collectionView.frame.height)
}
ImageCollectionViewCell
class ImageCollectionViewCell: UICollectionViewCell {
....
private let imageView: UIImageView = {
let img = UIImageView()
img.contentMode = .scaleAspectFill
img.translatesAutoresizingMaskIntoConstraints = false
return img
}()
....
}
ImageCollectionViewCell -> imageView Constraint
addSubview(imageView)
NSLayoutConstraint.activate([
leadingAnchor.constraint(equalTo: imageView.leadingAnchor),
trailingAnchor.constraint(equalTo: imageView.trailingAnchor),
topAnchor.constraint(equalTo: imageView.topAnchor),
bottomAnchor.constraint(equalTo: imageView.bottomAnchor)
])
UICollectionView FlowLayout Warning
The item height must be less than the height of the UICollectionView minus the section insets top and bottom values, minus the content insets top and bottom values.
The relevant UICollectionViewFlowLayout instance is , and it is attached to ; layer = ; contentOffset: {0, -44}; contentSize: {0, 0}; adjustedContentInset: {44, 0, 34, 0}> collection view layout: .
This is Keep Happening
https://gph.is/g/EqNL8jr

UICollectionView Warning Fix
if #available(iOS 11.0, *) { collectionView.contentInsetAdjustmentBehavior = .never }
else { automaticallyAdjustsScrollViewInsets = false }
Scale to fill was giving bigger image than UIImageView size
img.clipsToBounds = true

Related

UIImageView not resizing as circle and UILabel not resizing within StackView and Custom Collection Cell

I am trying to resize my UIImageView as a circle, however; every time I try to resize the UIImageView, which is inside a StackView along with the UILabel, I keep on ending up with a more rectangular shape. Can someone show me where I am going wrong I have been stuck on this for days? Below is my code, and what it's trying to do is add the image with the label at the bottom, and the image is supposed to be round, and this is supposed to be for my collection view controller.
custom collection view cell
import UIKit
class CarerCollectionViewCell: UICollectionViewCell {
static let identifier = "CarerCollectionViewCell"
private let imageView: UIImageView = {
let imageView = UIImageView()
imageView.frame = CGRect(x: 0, y: 0, width: 20, height: 20);
//imageView.center = imageView.superview!.center;
imageView.contentMode = .scaleAspectFill
imageView.layer.borderWidth = 4
imageView.layer.masksToBounds = false
imageView.layer.borderColor = UIColor.orange.cgColor
imageView.layer.cornerRadius = imageView.frame.height / 2
return imageView
}()
private let carerNamelabel: UILabel = {
let carerNamelabel = UILabel()
carerNamelabel.layer.masksToBounds = false
carerNamelabel.font = .systemFont(ofSize: 12)
carerNamelabel.textAlignment = .center
carerNamelabel.layer.frame = CGRect(x: 0, y: 0, width: 50, height: 50);
return carerNamelabel
}()
private let stackView: UIStackView = {
let stackView = UIStackView()
stackView.layer.masksToBounds = false
stackView.axis = .vertical
stackView.alignment = .center
stackView.backgroundColor = .systemOrange
stackView.distribution = .fillProportionally
stackView.translatesAutoresizingMaskIntoConstraints = false
return stackView
}()
override init(frame: CGRect) {
super.init(frame: frame)
configureContentView()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
private func configureContentView() {
imageView.clipsToBounds = true
stackView.clipsToBounds = true
carerNamelabel.clipsToBounds = true
contentView.addSubview(stackView)
configureStackView()
}
private func configureStackView() {
allContraints()
stackView.addArrangedSubview(imageView)
stackView.addArrangedSubview(carerNamelabel)
}
private func allContraints() {
setStackViewConstraint()
}
private func setStackViewConstraint() {
stackView.widthAnchor.constraint(equalTo: contentView.widthAnchor).isActive = true
stackView.heightAnchor.constraint(equalTo: contentView.heightAnchor).isActive = true
stackView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
stackView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
}
public func configureImage(with imageName: String, andImageName labelName: String) {
imageView.image = UIImage(named: imageName)
carerNamelabel.text = labelName
}
override func layoutSubviews() {
super.layoutSubviews()
stackView.frame = contentView.bounds
}
override func prepareForReuse() {
super.prepareForReuse()
imageView.image = nil
carerNamelabel.text = nil
}
}
Below here is my code for the CollectionViewControler
custom collection view
import UIKit
class CarerViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
private var collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
layout.itemSize = CGSize(width: 120, height: 120)
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.register(CarerCollectionViewCell.self, forCellWithReuseIdentifier: CarerCollectionViewCell.identifier)
collectionView.showsVerticalScrollIndicator = false
collectionView.backgroundColor = .clear
return collectionView
}()
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
view.addSubview(collectionView)
collectionView.translatesAutoresizingMaskIntoConstraints = false
// Layout constraints for `collectionView`
NSLayoutConstraint.activate([
collectionView.widthAnchor.constraint(equalTo: view.widthAnchor),
collectionView.heightAnchor.constraint(lessThanOrEqualTo: view.heightAnchor, constant: 600),
collectionView.topAnchor.constraint(equalTo: view.topAnchor, constant: 200),
collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor)
])
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CarerCollectionViewCell.identifier, for: indexPath) as! CarerCollectionViewCell
cell.configureImage(with: "m7opt04g_ms-dhoni-afp_625x300_06_July_20", andImageName: "IMAGE NO. 1")
return cell
}
}
Can somebody show or point to me what I am doing wrong, thank you
This is what I am trying to achieve
UIStackView could be tricky sometimes, you can embed your UIImageView in a UIView, and move your layout code to viewWillLayoutSubviews(), this also implys for the UILabel embed that also inside a UIView, so the containers UIViews will have a static frame for the UIStackViewto be layout correctly and whats inside them will only affect itself.

ScrollView Doesn't Scroll in collectionViewCell

I am creating a collage app. The functionality I am looking at in my collectionViewCell is exactly like this: How to make a UIImage Scrollable inside a UIScrollView?
What I have done till now:
Created a custom collectionViewCell embedded a UIScrollView in it and an imageView inside the scrollView. I have set their constraints. Following is my code for collectionViewCell :
override init(frame: CGRect) {
super.init(frame: frame)
// addSubview(scrollView)
insertSubview(scrollView, at: 0)
contentView.isUserInteractionEnabled = true
scrollView.contentMode = .scaleAspectFill
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(imageView)
scrollContentView.translatesAutoresizingMaskIntoConstraints = false
scrollView.isScrollEnabled = true
imageView.isUserInteractionEnabled = false
scrollView.delegate = self
scrollView.maximumZoomScale = 5.0
scrollView.backgroundColor = .red
scrollViewDidScroll(scrollView)
// scrollViewWillBeginDragging(scrollView)
let constraints = [
// Scroll View Constraints
scrollView.topAnchor.constraint(equalTo: contentView.topAnchor,constant: 0.0)
scrollView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor,constant: 0.0),
scrollView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor,constant: 0.0),
scrollView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor,constant: 0.0),
// ImageView Constraints
imageView.topAnchor.constraint(equalTo: self.scrollView.topAnchor),
imageView.bottomAnchor.constraint(equalTo: self.scrollView.bottomAnchor),
imageView.trailingAnchor.constraint(equalTo: self.scrollView.trailingAnchor),
imageView.leadingAnchor.constraint(equalTo: self.scrollView.leadingAnchor)
]
NSLayoutConstraint.activate(constraints)
}
Another issue I face here is if I do insertSubview() instead of addSubview my collectionView function for didselectItemAt works fine else if I use addSubView the didselectItemFunction doesn't execute. Code For didSelectItem :
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if selectedImage[indexPath.row] != UIImage(named: "empty-image") {
collectionViewCellClass.scrollView.isUserInteractionEnabled = true
collectionViewCellClass.scrollViewDidScroll(collectionViewCellClass.scrollView)
collectionViewCellClass.scrollView.showsHorizontalScrollIndicator = true
}else {
collectionViewCellClass.imageView.isUserInteractionEnabled = false
self.currentIndex = indexPath.row
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary){
imagePicker.delegate = self
imagePicker.allowsEditing = false
imagePicker.sourceType = .savedPhotosAlbum
present(imagePicker, animated: true, completion: nil)
}
}
}
Code for CellForItemAt IndexPath :
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.imageView.image = selectedImage[indexPath.item]
// TODO: Round corners of the cell
cell.scrollView.frame = CGRect(x: 0, y: 0, width: cell.frame.size.width, height: cell.frame.size.height)
// cell.scrollView.contentSize = CGSize(width: cell.imageView.image!.size.width * 2, height: cell.imageView.image!.size.height * 2)
cell.scrollView.contentSize = cell.imageView.image?.size ?? .zero
cell.scrollView.contentMode = .center
cell.scrollView.isScrollEnabled = true
// cell.scrollContentView.frame = CGRect(x: 0, y: 0, width: cell.frame.size.width, height: cell.frame.size.height)
cell.imageView.frame = CGRect(x: 0, y: 0, width: cell.imageView.image!.size.width, height: cell.imageView.image!.size.height)
// cell.imageView.clipsToBounds = true
cell.backgroundColor = .black
return cell
}
I have tried changing the size of ImageView = cell.frame.size still no luck and changed the size for scrollView Frame as well to imageView.image.size but for some reason scrollView doesn't scroll.
Insertview vs addSubview
addSubview: add the view at the frontmost.
insertSubview: add the view at a specific index.
when you add your scrollview it using addSubView method it will block all the user interaction for the view's that are below it. That's why didSelect event is not triggered.
see this question
To make the scrollview scroll you need to set its contentSize which should be greater than scrollview's frame. try adding an image whose size is greater than collectionview cell.
scrollView.contentSize = imageView.bounds.size
Try adding the scrollView to the cells contentView:
self.contentView.addSubview(scrollView)
I finally found the Solution, following is what worked for me :
if selectedImage[indexPath.row] != UIImage(named: "empty-image"){
cell.contentView.isUserInteractionEnabled = true
}else{
cell.contentView.isUserInteractionEnabled = false
}
The UIImage(named: "empty-image") is the image that appears when a user doesn't have made any selection for his image. I wrote the above code in the cellForItemAt function. Also, I had to set imageView.frame equal to the original width and height of the image.
cell.imageView.frame = CGRect(x: 0, y: 0, width: cell.imageView.image!.size.width, height: cell.imageView.image!.size.height)
The above solution solved my problem. Hopefully, it will help someone.

errors with UICollectionViewFlowLayout scrolling

I am setting up a UiCollectionView and I am trying to have the view scroll horizontally. The View is setup up and I can see labels and images but it does not scroll at all. The height of the collectionViewCell itself is 350 and how i am setting up the cell is
let SubView: UIView = {
let view = UIView()
view.backgroundColor = GREEN_Theme
view.layer.cornerRadius = 10
return view
}()
let headerLabel: UILabel = {
let label = UILabel()
label.text = "label"
label.font = UIFont.systemFont(ofSize: 30)
label.font = .boldSystemFont(ofSize: 30)
label.numberOfLines = 0
label.textColor = UIColor.black
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
addSubview(SubView)
SubView.anchors(top: topAnchor, topPad: 0, bottom: nil, bottomPad: 0, left: leftAnchor, leftPad: 0, right: rightAnchor, rightPad: 0, height: 1, width: self.bounds.width - 20)
addSubview(headerLabel)
headerLabel.anchors(top: SubView.bottomAnchor, topPad: 5 , bottom: nil, bottomPad: 0, left: safeAreaLayoutGuide.leftAnchor, leftPad: 15, right: nil, rightPad: 0, height: 50, width: 200)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
let recentCollectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.backgroundColor = UIColor.clear
collectionView.translatesAutoresizingMaskIntoConstraints = false
return collectionView
}()
func setupViews() {
backgroundColor = UIColor.clear
addSubview(recentCollectionView)
contentView.isUserInteractionEnabled = true
recentCollectionView.dataSource = self
recentCollectionView.delegate = self
recentCollectionView.isUserInteractionEnabled = true
recentCollectionView.backgroundColor = UIColor.blue
recentCollectionView.register(recentCell.self, forCellWithReuseIdentifier: cellID)
recentCollectionView.layer.zPosition = 1
recentCollectionView.topAnchor.constraint(equalTo: topAnchor, constant: 40).isActive = true
recentCollectionView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 5).isActive = true
recentCollectionView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -5).isActive = true
recentCollectionView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -40).isActive = true
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return reviews.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath) as! recentCell
cell.configureCell(reviews[indexPath.row])
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 100, height: frame.height - 5)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 100, left: 14, bottom: 0, right: 14)
}
}
class recentCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}
let imageView: UIImageView = {
let iv = UIImageView()
iv.image = UIImage(named: "rake")
iv.contentMode = .scaleAspectFill
iv.layer.cornerRadius = 16
iv.layer.masksToBounds = true
return iv
}()
let nameLabel: UILabel = {
let label = UILabel()
label.text = "Zach Wilcox"
label.font = UIFont.systemFont(ofSize: 14)
label.numberOfLines = 2
return label
}()
let categoryLabel: UILabel = {
let label = UILabel()
label.text = "Yard Work"
label.font = UIFont.systemFont(ofSize: 13)
label.textColor = UIColor.darkGray
return label
}()
let starControls = starStackView()
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupViews() {
addSubview(imageView)
addSubview(nameLabel)
addSubview(categoryLabel)
addSubview(starControls)
starControls.translatesAutoresizingMaskIntoConstraints = false
starControls.distribution = .fillEqually
imageView.frame = CGRect(x:0, y: 0, width: frame.width, height: frame.width)
nameLabel.anchors(top: imageView.bottomAnchor, topPad: 1, bottom: nil, bottomPad: 0, left: imageView.leftAnchor, leftPad: 0, right: nil, rightPad: 0, height: 20, width: 100)
categoryLabel.anchors(top: nameLabel.bottomAnchor, topPad: 1, bottom: nil, bottomPad: 0, left: imageView.leftAnchor, leftPad: 0, right: nil, rightPad: 0, height: 20, width: 100)
starControls.anchors(top: categoryLabel.bottomAnchor, topPad: 1, bottom: nil, bottomPad: 0, left: imageView.leftAnchor, leftPad: 0, right: nil, rightPad: 0, height: 20, width: 100)
}
In my console, I see
the item height must be less than the height of the UICollectionView minus the section insets top and bottom values, minus the content insets top and bottom values.
I have tried to set the background colors to blue in the recentCollectionView and the collectionView itself to see if the if the height of the cell is exceeding the height of the collectionView but it is not.
images below,
the first image, is the size of the entire contentView.
and this image is the size of the recentCollectionView
as we can see with the images, the recentCollectionView is not larger than the collectionView. Why am I seeing this error and why will my collectionViewFlowLayout not scroll?
I have found an answer shortly after posting my question but did not want to delete just in case some other newbie had the same problem. All I had to do was add the recentCollectionView to the contentView's subview not simply just addSubview.
contentView.addSubview(recentCollectionView)
super simple fix.

Troubleshooting an error: The behavior of the UICollectionViewFlowLayout is not defined because the item height must be less than the height

I have a ViewController that at the top, holds a UIView with a UITextView. Constrained to the bottom of the UIView is a UICollectionView that scrolls horizontally.
The UITextView resizes based on user typing in additional lines of text but I am getting an error because of some sizing issue between the collectionView and the collectionViewFlowLayout but I can't for the life of me work it out.
The code is as follows:
import UIKit
class ViewController: UIViewController {
let containerView = UIView()
var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
setupKeyboardObservers()
setupTopTextView()
setupCollectionView()
}
func setupTopTextView() {
view.backgroundColor = .lightGray
view.addSubview(containerView)
containerView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
containerView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0),
containerView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0),
containerView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0),
])
let textView = UITextView()
containerView.addSubview(textView)
textView.backgroundColor = .systemBackground
textView.translatesAutoresizingMaskIntoConstraints = false
textView.isScrollEnabled = false
textView.becomeFirstResponder()
textView.textContainer.maximumNumberOfLines = 0
NSLayoutConstraint.activate([
textView.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 50),
textView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 20),
textView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -20),
containerView.bottomAnchor.constraint(equalTo: textView.bottomAnchor, constant: 0)
])
textView.text = "This is a test"
}
func setupCollectionView() {
let flowLayout = UICollectionViewFlowLayout()
flowLayout.scrollDirection = .horizontal
flowLayout.minimumLineSpacing = 0
flowLayout.minimumInteritemSpacing = 0
collectionView = UICollectionView(frame: .zero, collectionViewLayout: flowLayout)
collectionView.backgroundColor = .systemYellow
view.addSubview(collectionView)
collectionView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
collectionView.topAnchor.constraint(equalTo: containerView.bottomAnchor, constant: 0),
collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0),
collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0),
collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0)
])
collectionView.isPagingEnabled = true
collectionView.dataSource = self
collectionView.delegate = self
collectionView.register(BasicCollectionViewCell.self, forCellWithReuseIdentifier: BasicCollectionViewCell.reuseIdentifier)
}
}
extension ViewController: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.frame.size.width, height: collectionView.frame.size.height)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
4
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: BasicCollectionViewCell.reuseIdentifier, for: indexPath) as! BasicCollectionViewCell
let backgroundColorOptions = [UIColor.systemGreen, .systemPurple, .brown, .systemRed]
cell.backgroundColor = backgroundColorOptions[indexPath.row]
return cell
}
}
The BasicCollectionViewCell literally has nothing yet as I am just trying to get these elements working and resizing correctly:
class BasicCollectionViewCell: UICollectionViewCell {
static let reuseIdentifier = "BASIC_COLLECTIONVIEW_CELL"
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
The error I get happens when the UITextView increases or decreases in height:
2020-07-02 16:34:06.922059+1000 collectionViewResizingTest[97611:1371485] The behavior of the UICollectionViewFlowLayout is not defined because:
2020-07-02 16:34:06.922175+1000 collectionViewResizingTest[97611:1371485] the item height must be less than the height of the UICollectionView minus the section insets top and bottom values, minus the content insets top and bottom values.
2020-07-02 16:34:06.922554+1000 collectionViewResizingTest[97611:1371485] The relevant UICollectionViewFlowLayout instance is <UICollectionViewFlowLayout: 0x7ffbfc016350>, and it is attached to <UICollectionView: 0x7ffbf9844600; frame = (0 94; 414 802); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x6000017c9200>; layer = <CALayer: 0x6000019d2ba0>; contentOffset: {0, 0}; contentSize: {1656, 816}; adjustedContentInset: {0, 0, 34, 0}; layout: <UICollectionViewFlowLayout: 0x7ffbfc016350>; dataSource: <collectionViewResizingTest.ViewController: 0x7ffbf9411ad0>>.
2020-07-02 16:34:06.922642+1000 collectionViewResizingTest[97611:1371485] Make a symbolic breakpoint at UICollectionViewFlowLayoutBreakForInvalidSizes to catch this in the debugger.
2020-07-02 16:34:08.131628+1000 collectionViewResizingTest[97611:1371485] The behavior of the UICollectionViewFlowLayout is not defined because:
2020-07-02 16:34:08.131766+1000 collectionViewResizingTest[97611:1371485] the item height must be less than the height of the UICollectionView minus the section insets top and bottom values, minus the content insets top and bottom values.
2020-07-02 16:34:08.131940+1000 collectionViewResizingTest[97611:1371485] The relevant UICollectionViewFlowLayout instance is <UICollectionViewFlowLayout: 0x7ffbfc016350>, and it is attached to <UICollectionView: 0x7ffbf9844600; frame = (0 107.5; 414 788.5); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x6000017c9200>; layer = <CALayer: 0x6000019d2ba0>; contentOffset: {0, 0}; contentSize: {1656, 768}; adjustedContentInset: {0, 0, 0, 0}; layout: <UICollectionViewFlowLayout: 0x7ffbfc016350>; dataSource: <collectionViewResizingTest.ViewController: 0x7ffbf9411ad0>>.
2020-07-02 16:34:08.132058+1000 collectionViewResizingTest[97611:1371485] Make a symbolic breakpoint at UICollectionViewFlowLayoutBreakForInvalidSizes to catch this in the debugger.
Any help would be greatly appreciated. I think it has something to do with the safe area at the bottom (this happens on devices in the simulator that have FaceID).
Fixed by setting the collectionView.contentInsetAdjustmentBehavior to .never

hidesbarsonswipe mutates view size

I am having trouble with this piece of code:
navigationController?.hidesBarsOnSwipe = true
My navigation controller's root view controller is a UICollectionViewController. The blue view below is a cell that represents the user's current screen. I think the problem is that I need to resize the cell when the navigation bar hides.
I set the cell size like this:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width, height: view.frame.height - 44)
}
I am not breaking any constraints, and I am very sure everything is set up properly. But when I swipe up, this happens:
Before
After
As you can see, the view gets shortened. I can't find those measurements anywhere in my code.
Is there a way to ensure that the view gets resized properly?
Put this in your viewDidLoad() and you should be good to go.
self.edgesForExtendedLayout = []
yourBlueView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(yourBlueView)
yourBlueView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
yourBlueView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
yourBlueView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
yourBlueView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
Edit:
Change yourBlueView to the name you've given that particular UIView. Let me know if you get stuck, but do try to figure it out first. That's the best way to learn it and retain it.
The bar on the bottom takes at least 44 and I notice it's going under the nav bar at the top. Remove your hard code sizing which is too high, and only use the auto layout
Second Edit: (This is a non-autolayout approach)
let reuseIdentifier = "Cell"
This code goes in viewDidLoad:
// Do any additional setup after loading the view, typically from a nib.
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.sectionInset = UIEdgeInsets(top: 20, left: 10, bottom: 10, right: 10)
let displaySize = UIScreen.main.bounds
let displayHeight = displaySize.height - 40
let displayWidth = displaySize.width
layout.itemSize = CGSize(width: displayWidth, height: displayHeight)
if let collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: layout) {
collectionView.dataSource = self
collectionView.delegate = self
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
collectionView.backgroundColor = UIColor.white
self.view.addSubview(collectionView!)
}

Resources