Minimum height for UICollectionView (Swift) - ios

Im trying to create a simple UICollectionView in Swift with a custom UICollectionViewCell. I have the following method in my UICollectionViewController to set the size of a cell;
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = (collectionView.frame.width / 3) - 10
let height = CGFloat(170)
return CGSize(width: width, height: height)
}
I then set constraints for the cell as follows;
private func setImageViewConstraints() {
itemImageView.translatesAutoresizingMaskIntoConstraints = false // enables Auto-Layout
itemImageView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true // center horizontally
itemImageView.topAnchor.constraint(equalTo: self.topAnchor, constant: 8).isActive = true // 8pt from top of cell
// 1:1 Aspect Ratio
itemImageView.widthAnchor.constraint(equalToConstant: (self.frame.width - 4)).isActive = true
itemImageView.heightAnchor.constraint(equalTo: itemImageView.widthAnchor).isActive = true
}
private func setupLabelConstraints() {
itemLabel.translatesAutoresizingMaskIntoConstraints = false
itemLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
itemLabel.leftAnchor.constraint(equalTo: itemImageView.leftAnchor, constant: 0).isActive = true
itemLabel.rightAnchor.constraint(equalTo: itemImageView.rightAnchor, constant: 0).isActive = true
itemLabel.topAnchor.constraint(equalTo: itemImageView.bottomAnchor, constant: 4).isActive = true
itemLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -4).isActive = true
}
However, the height of the cell varies, depending on the height of it's content, for example;
How can I set the height of the cells so they are all the same?
Thanks!

Related

Max width for content view of UICollectionView

A common pattern in UI is to maximize the size of the view up to some point and after that fill the rest of its superview with the spaces.
When using AutoLayout, it can be achieved easily with width <= X constraint. But when using this with UICollectionView, the scroll area matches the size of UICollectionView, so the sides are unscrollable which is unwanted for me.
So, the only way I found to achieve the behavior is to use the proper layout inside the cells themselves. I consider this as a not very good design decision (especially when you have multiple cells). But are there any alternatives available?
We can accomplish this by subclassing UICollectionView and implementing hitTest(_:with:).
What we'll do is extend the "touch area" wider than the collection view itself:
class ExtendedCollectionView: UICollectionView {
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if self.bounds.contains(point) {
// touch is inside self.bounds, so
// send it on to super (i.e. "normal" behavior)
// so we can select a cell on tap
return super.hitTest(point, with: event)
}
if self.bounds.insetBy(dx: -self.frame.origin.x, dy: 0).contains(point) {
// touch is outside self.bounds, but
// it IS inside bounds extended left and right, so
// capture the touch for self
return self
}
// touch was outside self.bounds (and outside our extended bounds), so
// send it on to super (i.e. "normal" behavior)
// so the rest of the view hierarchy (buttons, etc)
// can receive the gesture
return super.hitTest(point, with: event)
}
}
You can now use ExtendedCollectionView just as you would use UICollectionView, except you'll be able to scroll it starting from left or right, outside of its bounds.
Here's a complete example:
class ViewController: UIViewController {
var myData: [String] = []
// we'll use these colors for the cell backgrounds
let colors: [UIColor] = [
.systemRed, .systemGreen, .systemBlue,
.systemPink, .systemYellow, .systemTeal,
]
// our "extended collection view"
var collectionView: ExtendedCollectionView!
let cellSize: CGSize = CGSize(width: 80, height: 100)
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Extended CollectionView"
// always respect the safe area
let g = view.safeAreaLayoutGuide
// let's add a "background" image view, sized to fit the view
// so we can easily see the reults
if let img = UIImage(named: "sampleBKG") {
let v = UIImageView()
v.image = img
v.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(v)
view.sendSubviewToBack(v)
NSLayoutConstraint.activate([
v.topAnchor.constraint(equalTo: g.topAnchor, constant: 0.0),
v.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 0.0),
v.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: 0.0),
v.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: 0.0),
])
}
// fill myData array with 20 strings
// of different lengths to show this
// works with dynamic width cells
let strs: [String] = [
"Short",
"Bit Longer",
"Much Longer String",
]
for i in 0..<20 {
myData.append("C: \(i) \(strs[i % strs.count])")
}
// set the flow layout properties
let fl = UICollectionViewFlowLayout()
fl.estimatedItemSize = CGSize(width: 50, height: 100)
fl.scrollDirection = .horizontal
fl.minimumLineSpacing = 8
fl.minimumInteritemSpacing = 8
// create an instance of ExtendedCollectionView
collectionView = ExtendedCollectionView(frame: .zero, collectionViewLayout: fl)
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.backgroundColor = .clear
view.addSubview(collectionView)
// let's make the collection view
// 80% of the width of the view's safe area
let cvWidthPercent = 0.8
// let's add a label below our custom view
// the same percentage width, so we can
// easily see the layout
let v = UILabel()
v.backgroundColor = .green
v.translatesAutoresizingMaskIntoConstraints = false
v.textAlignment = .center
v.text = "\(cvWidthPercent * 100)%"
view.addSubview(v)
NSLayoutConstraint.activate([
// let's put our collection view
// 80-pts from the top
collectionView.topAnchor.constraint(equalTo: g.topAnchor, constant: 80.0),
// centered Horizontally
collectionView.centerXAnchor.constraint(equalTo: g.centerXAnchor),
// height equal to cell Height
collectionView.heightAnchor.constraint(equalToConstant: cellSize.height),
// 80% of the width of the safe area
collectionView.widthAnchor.constraint(equalTo: g.widthAnchor, multiplier: cvWidthPercent),
// constrain label 8-pts below the collection view
v.topAnchor.constraint(equalTo: collectionView.bottomAnchor, constant: 8.0),
// centered Horizontally
v.centerXAnchor.constraint(equalTo: g.centerXAnchor),
// same percentage width
v.widthAnchor.constraint(equalTo: g.widthAnchor, multiplier: cvWidthPercent),
])
collectionView.dataSource = self
collectionView.delegate = self
collectionView.register(MyDynamicCVCell.self, forCellWithReuseIdentifier: "cvCell")
}
}
extension ViewController: UICollectionViewDataSource, UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return myData.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cvCell", for: indexPath) as! MyDynamicCVCell
cell.contentView.backgroundColor = colors[indexPath.item % colors.count]
cell.label.text = myData[indexPath.item]
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("Did Select Cell At:", indexPath)
}
}
a simple dynamic-width cell
class MyDynamicCVCell: UICollectionViewCell {
let label: UILabel = {
let v = UILabel()
v.translatesAutoresizingMaskIntoConstraints = false
v.textAlignment = .center
v.backgroundColor = UIColor(white: 0.9, alpha: 1.0)
return v
}()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() -> Void {
contentView.addSubview(label)
NSLayoutConstraint.activate([
label.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor),
label.trailingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.trailingAnchor),
label.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
])
}
}
The result looks like this:
When you run it, you'll see that you can scroll horizontally, even if you start dragging from the left or right of the cells.

Self sizing UICollectionView with autolayout

I'm trying to figure out is it possible for UICollectionView to calculate it's own height using autolayout? My custom cells are built on autolayout and the UICollectionViewFlowLayout.automaticSize property for itemSize seems to be working, but the size of UICollectionView itself should be set. I believe that this is normal behavior, since the collection can have bigger size than it's cells, but maybe it is possible to make height of the content view of UICollectionView to be equal to cell with some insets?
Here is the code for test UIViewController with UICollectionView
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
var collectionView: UICollectionView?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .green
let layout = UICollectionViewFlowLayout()
layout.estimatedItemSize = CGSize(width: UIScreen.main.bounds.width, height: 100)
layout.itemSize = UICollectionViewFlowLayout.automaticSize
layout.scrollDirection = .horizontal
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 0
collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
if let collectionView = collectionView {
collectionView.showsHorizontalScrollIndicator = false
collectionView.isPagingEnabled = true
collectionView.register(CollectionViewCell.self,
forCellWithReuseIdentifier: "CollectionViewCell")
collectionView.backgroundColor = .clear
collectionView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(collectionView)
collectionView.delegate = self
collectionView.dataSource = self
NSLayoutConstraint.activate([
collectionView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
collectionView.leftAnchor.constraint(equalTo: view.leftAnchor),
collectionView.rightAnchor.constraint(equalTo: view.rightAnchor),
// I want to get rid of this constraint
collectionView.heightAnchor.constraint(equalToConstant: 200)
])
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
5
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell",
for: indexPath) as? CollectionViewCell else {
return UICollectionViewCell()
}
return cell
}
}
And for custom cell
final class CollectionViewCell: UICollectionViewCell {
var mainView = UIView()
var bigView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .yellow
return view
}()
var label: UILabel = {
let label = UILabel()
label.text = "Here is text"
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
var anotherLabel: UILabel = {
let label = UILabel()
label.text = "Here may be no text"
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
let inset: CGFloat = 16.0
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(mainView)
mainView.translatesAutoresizingMaskIntoConstraints = false
mainView.backgroundColor = .white
addSubview(bigView)
addSubview(label)
addSubview(anotherLabel)
NSLayoutConstraint.activate([
mainView.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width),
mainView.topAnchor.constraint(equalTo: topAnchor),
mainView.leftAnchor.constraint(equalTo: leftAnchor),
mainView.rightAnchor.constraint(equalTo: rightAnchor),
mainView.bottomAnchor.constraint(equalTo: bottomAnchor),
bigView.topAnchor.constraint(equalTo: mainView.topAnchor, constant: inset),
bigView.leftAnchor.constraint(equalTo: mainView.leftAnchor, constant: inset),
bigView.rightAnchor.constraint(equalTo: mainView.rightAnchor, constant: -inset),
bigView.bottomAnchor.constraint(equalTo: mainView.bottomAnchor, constant: -inset),
label.topAnchor.constraint(equalTo: bigView.topAnchor, constant: inset),
label.leftAnchor.constraint(equalTo: bigView.leftAnchor, constant: inset),
label.rightAnchor.constraint(equalTo: bigView.rightAnchor, constant: -inset),
anotherLabel.topAnchor.constraint(equalTo: label.bottomAnchor, constant: inset),
anotherLabel.leftAnchor.constraint(equalTo: bigView.leftAnchor, constant: inset),
anotherLabel.rightAnchor.constraint(equalTo: bigView.rightAnchor, constant: -inset),
anotherLabel.bottomAnchor.constraint(equalTo: bigView.bottomAnchor, constant: -inset)
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
And maybe someone, who knows the answer also could tell whether it's possible to later put this paging collection into UITalbleViewCell and make size of the cell change with selected item in the collection? I provide screenshot of the collection I'm trying to make:
Item's without second text label will have smaller height, than items on the picture
Screenshot
Solution 1:
Get collection view content size from collectionViewLayout :
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// Set your collection view height here.
let collectionHeight = self.yourCollectionView.collectionViewLayout.collectionViewContentSize.height
}
Solution 2:
Use KVO.
// Register observer
self.yourCollectionView.addObserver(self, forKeyPath: "contentSize", options: [.new, .old, .prior], context: nil)
#objc override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "contentSize" {
// content size changed. Set your collection view height here.
let contentSize = change?[NSKeyValueChangeKey.newKey] as? CGSize {
print("contentSize:", contentSize)
}
}
// Remove register observer
deinit {
self.yourCollectionView.removeObserver(self, forKeyPath: "contentSize")
}
Solution 3:
Assign this class to UICollectionView. If you set height constraint from storyboard then set and enable remove at runtime.
class DynamicCollectionView: UICollectionView {
override func layoutSubviews() {
super.layoutSubviews()
if !__CGSizeEqualToSize(bounds.size, self.intrinsicContentSize) {
self.invalidateIntrinsicContentSize()
}
}
override var intrinsicContentSize: CGSize {
var size = contentSize
size.height += (contentInset.top + contentInset.bottom)
size.width += (contentInset.left + contentInset.right)
return size
}
}

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

rowHeight of cell not adjusting to content increase

I use below code to add constraints programatically, no story board used
cell.descriptionDetail.leadingAnchor.constraint(equalTo: cell.contentView.leadingAnchor, constant: 15).isActive = true
cell.descriptionDetail.topAnchor.constraint(greaterThanOrEqualTo: cell.contentView.topAnchor, constant: 20).isActive = true
cell.descriptionDetail.trailingAnchor.constraint(equalTo: cell.contentView.trailingAnchor, constant: -20).isActive = true
cell.descriptionDetail.bottomAnchor.constraint(greaterThanOrEqualTo: cell.contentView.bottomAnchor, constant: 10).isActive = true
Now i use this in viewDidLaod
detailTableView.rowHeight = UITableView.automaticDimension
detailTableView.rowHeight = 40
even if i remove height constraints on all cell the row height does. not adjust, if i remove
detailTableView.rowHeight = 40
and add detailTableView.estimatedRowHeight = 40, i get error, currently this is what happens , content overlapping cells
UPDATE MY ENTIRE CODE OF FILE WHERE THE CELL IS BEING CREATED AND CONSTRAINED
let cell = detailTableView.dequeueReusableCell(withIdentifier: String(describing: TextOnlyCell.self), for: indexPath) as! TextOnlyCell
view.addSubview(cell.descriptionDetail)
view.addSubview(cell)
cell.descriptionDetail.numberOfLines = 0
cell.descriptionDetail.lineBreakMode = .byWordWrapping
cell.descriptionDetail.translatesAutoresizingMaskIntoConstraints = false
cell.descriptionDetail.widthAnchor.constraint(greaterThanOrEqualToConstant: 100).isActive = true
cell.descriptionDetail.heightAnchor.constraint(greaterThanOrEqualToConstant: 20).isActive = true
///Constraints
cell.descriptionDetail.leadingAnchor.constraint(equalTo: cell.leadingAnchor, constant: 15).isActive = true
cell.descriptionDetail.topAnchor.constraint(greaterThanOrEqualTo: cell.topAnchor, constant: 10).isActive = true
cell.descriptionDetail.trailingAnchor.constraint(equalTo: cell.trailingAnchor, constant: -5).isActive = true
cell.descriptionDetail.bottomAnchor.constraint(greaterThanOrEqualTo: cell.bottomAnchor, constant: 10).isActive = true
cell.descriptionDetail.text = restaurant.description
return cell
Add this method in your class... and be sure that your constraints are attached with top and bottom ... to help automaticDimension to calculate height
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableView.automaticDimension
}

Disabling uicollectionview scroll makes uicollectionview smaller

I have got this uicollectionview
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.minimumLineSpacing = 90
collectionView = UICollectionView(frame: CGRect(x:0,y:0,width:0,height:0), collectionViewLayout: layout)
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.isScrollEnabled = false
collectionView.heightAnchor.constraint(equalToConstant: collectionView.contentSize.height).isActive = true collectionView.topAnchor.constraint(equalTo:PostsTab.bottomAnchor).isActive = true
collectionView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor).isActive = true
collectionView.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true
collectionView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
Now this collectionView is inside scrollView.On top of collectionview there is another view and it all looks like this
Now when i scroll down i want that UIView that is on top of collectionView to be left behind that's why i added isScrollEnabled = false,without that when i scroll down uiview stays on a fixed position
like this
override func viewDidAppear(_ animated: Bool) {
scrollView.contentSize = CGSize(width:1,height: 2400)
collectionView.heightAnchor.constraint(equalToConstant: collectionView.contentSize.height).isActive = true
}

Resources