UICollectionView layout change when frame size changes - ios

I'm working with a UICollectionView but I have a weird behaviour.
I want a horizontal scroll, small cell height ( smaller than the UICollectionView height).
Tapping a button will increase even more the height of the collection.
The problem is that the layout of my cells is changing also.
I want the collection view height to increase with the cells staying in the same position.
Here attached 2 screen captures (before/after button touched).
Here is my code:
var smallLayout:UICollectionViewFlowLayout = UICollectionViewFlowLayout();
smallLayout.scrollDirection = .Horizontal
var itemHeight = 100
smallLayout.itemSize = CGSizeMake(150, itemHeight);
var bottomDist:CGFloat = 1
var topDist = collHeight - itemHeight - bottomDist
smallLayout.sectionInset = UIEdgeInsets(top: topDist, left: 2, bottom: bottomDist, right: 2)
smallLayout.minimumInteritemSpacing = 15
smallLayout.minimumLineSpacing = 10
So, when touching the button I have the following code:
let viewHeight = CGRectGetHeight(self.view.frame)
let viewWidth = CGRectGetWidth(self.view.frame)
var collHeight:CGFloat = 600
var collYPosition = viewHeight-CGFloat(collHeight)-20
var rect = CGRectMake(0, CGFloat(collYPosition), CGFloat(viewWidth), CGFloat(collHeight))
dishCollectionView.frame = rect
So, I cannot understand why my layout is changing.
I want to have my cell at the bottom.

Perhaps if you reset the top of your sectionInset to accommodate for the additional height, i.e. an updated topDist calculation. Try adding something like this to you on touch code:
var bottomDist:CGFloat = 1
var topDist = collHeight - itemHeight - bottomDist
dishCollectionView.collectionViewLayout.sectionInset = UIEdgeInsets(top: topDist, left: 2, bottom: bottomDist, right: 2)
dishCollectionView.collectionViewLayout.invalidateLayout()

Related

UICollection spacing not working I Don't wont any spacing in uicollectionview

I have tried following but not working
self.hCltVw.constant = (rowHeight * 8.0)
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
layout.itemSize = CGSize(width: size, height:rowHeight)
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 0
collectionView.reloadData()
collectionView.collectionViewLayout = layout
But still spaing in collectionview row. Dont know why spacing is not working also if i add + 80 in collectionview height spacing is automatically removed.
My Xib Setup
NOTE: the strange thing is if I increase collection-view height
constant then space is decreasing.
i had same problem, i solved it by this may be it will helpful for you .
in storybord select your collectionview and change some settings in attribute inspector.
set estimate size = none
in section insets top,bottom,left,right set this all value 0
set min Spacing (for cell , for line both) = 0
[edited]
try this:-
let width = (view.frame.size.width) / 3
let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = CGSize(width: width, height: width)

Uicollection view dynamic height but fixed width

I am working with UICollectionView I have 4 different kind of cells. Every cell is designed in xib file . when i load them in collection view it goes out of screen. i don't know why it is happening. Some cells have fixed height while some have dynamic height (depends on data coming from API). So is there any possible way to solve this issue.
i have tried Estimate size automatic to dynamic
override func awakeFromNib() {
super.awakeFromNib()
self.contentView.translatesAutoresizingMaskIntoConstraints = false
let screenwidth = UIScreen.main.bounds.size.width
widthAnchor.constraint(equalToConstant: screenwidth-20)
}
func setSize () {
let layout = mainCollection.collectionViewLayout as! UICollectionViewFlowLayout
layout.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)}
}
try this!
let screenWidth = self.CollecionView.frame.width

UICollectionview dynamic height issue

I want to achieve the following outcome
I have implemented collectionview horizontal scrolling. It is working fine when scrolling is enabled. However, when scrolling is disabled and the flow changes to vertical, only the first row is displayed and collection view height is not increased.
Q:- How can I get collection view full height when scrolling is disabled?
I have tried the following code for getting height and it returns 30.0.
let height = self.collectionTags.collectionViewLayout.collectionViewContentSize.height; // 30.0
And this one returns 0.0
let height = self.collectionTags.contentSize.height // 0.0
Here is the collectionview layout code
if let flowLayout = collectionTags.collectionViewLayout as? UICollectionViewFlowLayout {
flowLayout.estimatedItemSize = CGSize(width: 1, height: 30.0)
flowLayout.itemSize = UICollectionViewFlowLayoutAutomaticSize
}
I ran into a similar problem. The solution for me was to add height constraint to the collectionView and calculating its height depending on the items that I wanted to display. Here is a snippet I created:
// Items that will be displayed inside CollectionView are called tags here
// Total tags width
var tagWidth:CGFloat = 0
// Loop through array of tags
for tag in self.tagsArray {
// Specifying font so we can calculate dimensions
let tagFont = UIFont(name: "Cabin-Bold", size: 17)!
let tagAttributes: [String : Any]? = [
NSFontAttributeName: tagFont,
NSForegroundColorAttributeName: UIColor.white,
]
// Get text size
let tagString = tag as NSString
let textSize = tagString.size(attributes: tagAttributes ?? nil)
// Add current tag width + padding to the total width
tagWidth += (textSize.width + 10)
}
// Calculate number of rows
var totalRows = tagWidth / (self.bounds.width - 40)
totalRows = totalRows.rounded(.up)
// Calculate height and apply it to the CollectionView height constraint
estimatedCollectionViewHeight = Float(CGFloat(totalRows * 29))
collectionViewHeight.constant = CGFloat(estimatedCollectionViewHeight)

Place the collection view cells vertically instead of horizontally?

How to design UICollectionView in such a way that it fills the collection view cells vertically (column-wise) instead of filling horizontally (row-wise)?
The collection view should be vertically scrollable, I should not change the size of the collection cell and determine the number of rows dynamically?
(YOUR_COLLECTIONVIEW_NAME.collectionViewLayout as? UICollectionViewFlowLayout).scrollDirection = .horizontal
I use this code for it:
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
myCollectionView.collectionViewLayout = layout
For limited number of rows you can set collectionView height and set height of cell and spacings. For example, if you need 2 cells in column, you will write:
layout.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
layout.itemSize = CGSize(width: self.collectionView.frame.size.width / 5, height: self.collectionView.frame.size.height / 2.5)
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 0
you can change this parameters like you need

Equal horizontal spacing UICollectionView, including insets - UICollectionViewFlowLayout?

I'm trying to create equal horizontal spacing between two UICollectionViewCell and between a UICollectionViewCell an the screen border. It should look like this.
I think it is possible to use UICollectionViewFlowLayout to adjust the width of every UICollectionViewCell, so they have equal spacings regardless of the phone's size. There should always only be 3 cells on each row.
First of all you should add constants for all parameters of UICollectionView to the controller:
let itemsPerRow = 3
let spaceBetweenItems: CGFloat = 20.0
let spaceBetweenLines: CGFloat = 40.0
let itemHeight: CGFloat = 50.0
You mentioned that item's width should be adjustable. You can calculate it with this function:
var itemWidth: CGFloat {
return (self.collectionView.frame.width - CGFloat(self.itemsPerRow + 1) * self.spaceBetweenItems) / CGFloat(self.itemsPerRow)
}
Of course you need to customise layout of your UICollectionView instance:
var collectionViewLayout: UICollectionViewFlowLayout {
let result = UICollectionViewFlowLayout()
result.itemSize = CGSize(width: self.itemWidth, height: self.itemHeight)
result.minimumInteritemSpacing = self.spaceBetweenItems
result.minimumLineSpacing = self.spaceBetweenLines
result.sectionInset = UIEdgeInsets(top: 0.0, left: self.spaceBetweenItems, bottom: 0.0, right: self.spaceBetweenItems)
result.scrollDirection = .vertical
return result
}
And in the function viewDidLoad or your controller you should call setupCollectionView(). Here is a code of this function:
func setupCollectionView() {
self.collectionView.frame = self.view.frame
self.collectionView.collectionViewLayout = self.collectionViewLayout
}
You will see something like this:

Resources