How to create like this collection view with different cell size inside table view cell and also inside collection view cell image need to download from url cell
i tried below code, but last 2 small cells going up , and also when the image downloaded from url collection view is not loading until manually touch collection view
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let cVWidth = collectionView.frame.width
let biggerCellWidth = (cVWidth / 2.5) - 5
if indexPath.row == 2 || indexPath.row == 3 {
let testValue:CGFloat = 3
return CGSize(width: (biggerCellWidth / 2) - testValue , height: (biggerCellWidth / 2) - testValue )
}
return CGSize(width: biggerCellWidth, height: biggerCellWidth)
}
For creating a collection view inside a table view go to this link
There is a method in UICollectionViewDelegateFlowLayout
collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
where you can set the size of collection view cell size. Say you want to set the third and fourth cell's height as half of the collection view and square in size. Put this condition
if indexPath.row == 2 || indexPath.row == 3
{
let height = collectionView.bounds.size.height / 2
return CGSize(width: height, height: height)
}
Related
I'm trying to have collection view with 2 column but dynamic height.
I have used Autolayout and given required constraints to the Cell
By this way I can calculate the dynamic height but its column grids fails.
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! MenuListCollectionViewCell
cell.frame.size.width = collectionView.frame.width/2
cell.menuList = self.menuList[indexPath.row]
let resizing = cell.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize, withHorizontalFittingPriority: UILayoutPriority.required, verticalFittingPriority: UILayoutPriority.fittingSizeLevel)
return resizing
}
This is how I want it to look
Not sure what you mean by "its column grid fails".
Anyway, you need to write a custom collection view layout. The default one (UICollectionViewFlowLayout) allows you to change height of the cells by providing the sizeForItemAt, but that won't change the behavior of the layout that will always arrange cells in rows of the same height (the height of the highest cell).
If I understood correctly, you just want the same layout of this raywenderlich tutorial.
Basically:
Create a subclass of UICollectionViewLayout implementing it's methods:
collectionViewContentSize: return width and height of the collection view content
prepare: where you can calculate the sizes of cells and
collectionView content
layoutAttributesForElements: where you
return an array of UICollectionViewLayoutAttributes in the given
rect
layoutAttributesForItem: where you return the same kind
of attributes, this time specific for an item
assign an object of this class to the collection view layout property
you can use this
This code is somehow written that you can change section inset or minimumInteritemSpacing and this calculate and resize with this parameters
you can use this code or download project from Github
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let numberofItem: CGFloat = 2
let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout
let collectionViewWidth = self.collectionView.bounds.width
let extraSpace = (numberofItem - 1) * flowLayout.minimumInteritemSpacing
let inset = flowLayout.sectionInset.right + flowLayout.sectionInset.left
let width = Int((collectionViewWidth - extraSpace - inset) / numberofItem)
return CGSize(width: width, height: width)
}
I was able to achieve your desired outcome by doing the following.
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 20
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: (self.view.frame.size.width/2 - 5), height: 100)
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = customCollectionView.dequeueReusableCell(withReuseIdentifier: "test", for: indexPath)
cell.layer.backgroundColor = UIColor.red.cgColor
return cell
}
Make sure you have implemented all the correct delegates
UICollectionViewDelegate
UICollectionViewDatasource
UICollectionViewDelegateFlowLayout
where you see height: make it your own desired height as you have specified in your question.
KEY: Make sure in your storyboard you have set the estimate size of the collection view to NONE -> otherwise the code will not work as expected
after update to ios 12 and xcode 10 the collectionView with cell sizeing cell does not work correctly anymore.
i have this layout in xcode
the view is like this.
and this is how it looks now.
i have tried to set the collectionview view a widht constraint and modified in the
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
cell.widthConstraint.constant = UIScreen.main.bounds.width / 3
but nothing happens.
You were using the wrong method to set the cells size.
Instead of collectionView(_:cellForItemAt:) use collectionView:layout:sizeForItemAtIndexPath:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let itemHeight = 60
let itemWidth = UIScreen.main.bounds.width / 3
return CGSize(width: itemWidth, height: itemHeight)
}
Also, you can set up items size using Interface Builders Size Inspector, but in that case, the size of your cells will be absolute. If you want it to be 1/3 of screen width, you need to use the layout delegate.
I'm new to iOS and Swift, I'm trying to create a UICollectionView for the first time.
Something is not quite right when running what I made. Here's what it looks like in my storyboard:
But when I run:
Top grey area became longer than before and bottoms of the cells seem clipped. I just wrote few lines of code to make the cells' height equal to the collection view's.
let height = collectionView.frame.height
cell.frame.size.height = height
return cell
Any suggestions?
Swift 4 code is here
1) Uncheck the Automatic field of the Row Height in the attribute inspector.
2) Then set the delegate funcitons
extension ViewController : UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
var width = CGFloat(80) //change "80" with your cell width
return CGSize(width: width ,height : self.collectionView.frame.height)
}
}
Please use collectionViewLayout to give a size for an item,
class YourController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
and
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let height = collectionView.frame.height
let width = UIScreen.main.bounds.width / 3
let size = CGSize(width: width, height: height)
return size
}
You can make changes from storyboard or from code. I have done from storyboard as shown in image.
And also write this method in your view controller to give a size to your item. For that inherit UICollectionViewDelegateFlowLayout method in your view controller.
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let size = collectionView.frame.width / 3
return CGSize(width: size - 20, height: size - 20 )
}
Note: This is just an example. You can set your collection view cell frame.
To change height in a collection view, do not change the cell frame height. There is another delegate for the collection view to set cell height and width.
extension ViewControll : UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
return CGSize(width: anyWidth, height: collectionView.frame.size.height)
}
}
Here, anyWidth means whatever width you put. It's up to you
I want to use collection view for show user's instagram photos like Tinder. I placed a collectionview and enabled paging. But i don't know how to show 6 photos for each page. How can i do this?
This is what i want:
First page:
Second Page:
I used all spacing settings zero because setting spacing from storyboard problem for different screen sizes.
My collection view's settings and result:
Result:
So i want to show 6 photos per page. How to achive this?
To show the specific number of cells you want, you have to calculate the size of the cells. Something like this:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let numberOfRows = 2
let numberOfColumns = 3
let height = collectionView.frame.size.height / numberOfRows
let width = collectionView.frame.size.width / numberOfColumns
let cellSize = CGSize(width: width, height: height)
return cellSize
}
Since your layout configuration is static you can calculate it just once to make it faster:
class MyVC: UIViewController {
private let cellSize: CGSize = CGSize(width: collectionView.frame.width/numberOfColumns, height: collectionView.frame.height/numberOfRows) // or create a computed property
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return cellSize
}
}
This code is untested, maybe you have to add some padding but you get the idea. Another option would be to implement your own UICollectionViewLayout subclass
I have setup my collection view in a way, that my first image comes full size to the right and half the size of screen vertically with the following code
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
if indexPath.row == 0 {
return CGSize(width: self.collectionView.frame.width, height: ( self.collectionView.frame.height / 2 ))
}
let width = self.collectionView.frame.width / 3 - 1
return CGSize(width: width, height: width)
}
it works ok. But when collection view has only 2 item then the second item comes in the middle rather that on the left.
How to fix this ??