Set X rows in UICollectionview - swift

I have an UICollectionView inside of an UIViewcontroller. I want to know how to set a maximum of cells in each row.
This question was asked before here: UICollectionView display 3 items per row
This is answered however in an Objective C. Therefore I can not understand the answer. Also, this is done programmatically. Is there a way to do this in the interface builder? Edit: 3 people reported this as a duplicate. Yes, of course it's a duplicated question, I literately already mentioned that. Again: the questions are given in Objective C which I can not read. Therefore the answer of this topic should differ from the the topic I already mentioned.
So this is the case. I want to know if its possible to display 3 items in a row. So if there are 4 items, the first row displays 3 cells and the second row displays the other cell. I tried it with autolayout, but this is not how it works I guess. The cell's size remains the same. This way the cell's size is the same on all devices. This is not what I want. The width and height of the cell should be proportional to the view's width and heights. Let say view.width * 0.25 and height view.height * 0.5.
Edit: I already tried this:
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
return CGSize(width: collectionView.bounds.size.width/4 - 0, height: collectionView.bounds.size.height/4 - 0)
}
And played with the number's (4 and 0) but not the result I wanted.
Edit: Found it out
Final answer: if you want to have 3 rows, and make sure minimal spacing is higher than 0:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.bounds.size.width/4 - 0, height: collectionView.bounds.size.height/1.5)
}

Related

Issues with resizing my UICollectionViewCell

I am currently trying to resize my cell within my CollectionView. I have already implemented the dataSource, CollectionViewDelegate and CollectionViewDelegateFlowLayout.
This is the code I have for the latter:
extension ViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout
collectionViewLayout: UICollectionViewLayout, sizeForItemAt
indexPath: IndexPath) -> CGSize
{
return CGSize(width: 100.0, height: 100.0)
}
}
The problem is that when I head over to my storyboard and select my CollectionView and then go to the Attributes Inspector to switch "Estimate Size" from "Automatic" to "None," I would get three columns after running my app [Image #1].
The result I am looking for is to be able to have one middle column with a bigger cell as I show on Image #2.
Has anybody dealt with this problem before?
In order to show a collection view cells as a list, you can change your cell width equals to the width of the collection view. Giving constant width will not work for different device size.
func collectionView(_ collectionView: UICollectionView, layout
collectionViewLayout: UICollectionViewLayout, sizeForItemAt
indexPath: IndexPath) -> CGSize
{
let width = collectionView.frame.width
return CGSize(width: width, height: 100.0)
}
}
And give your desired constraint values for the inner rectangular view to achieve the desired look. Make collectionView cell background to clear.

UICollectionView Layout Buggy

Hey guys I’d love some help on an issue I am facing with uicollection view. It’s a uicollectionview inside a .xib with custom cells that I’m loading through UINibs. I almost get the result I’m looking for but there’s some awkward spacing. Also as a note I’m using the layout delegate to calculate the size of the text and then setting the cell but it’s still awkward every time I generate it. Thanks guys.
Example 1
Example 2
Here is the code I am using:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
// dataArary is the managing array for your UICollectionView.
let item = self.visibleSuggestion[indexPath.item]
var itemSize = item.size(withAttributes: [
NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 13)
])
itemSize.width += 20
itemSize.height += 15
return itemSize
}

Apply sizeForItemAt to only one collectionView

I'm using sizeForItemAt to set the cell size for ONE view controller, but it seems that I have to return a result also for the other CollectionViews, the problem is that I don't have the size value for the others since it is defined in the storyboard. I'm trying this:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
if categorie_cv == collectionView {
let size: CGSize = categorie[indexPath.row].size(withAttributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 17.0)])
return CGSize(width: size.width + 40.0, height: categorie_cv.bounds.size.height)
} else if collectionView == risultati {
return THIS VALUE IS SET IN THE STORYBOARD
} else {
return THIS VALUE IS SET IN THE STORYBOARD
}
}
No, unfortunately you can not tell it to automatically use the intrinsic size of the element derived from its layout.
However if your layout would really allow for the intrinsic size to be configured non-ambiguously through AutoLayout/it's content, you can call UIView.intrinsicContentSize, possibly mixing with layoutIfNeeded call. I am not positive that this solution is 100% working though.
If I were you I would seek not the way to assign a delegate and implement sizeForItemAt but rather do define this size ALSO in the matters of the cell itself.
And by the way, actually, it's a bit of "will turn out NOT as you expected it to" to let the cells to determine their their content size. This can be very helpful and logical with UITableView, but layout calculation in case of UICollectionView is better to be determined by simpler, calculative approach.
That is, it's cheap to compute the width to be half of bounds width of collectionView and equal to height - rather then let the content freely layout itself using very dynamic content-compression rules and constraint priority evaluation. Typically, having all cells have absolutely nothing in common in terms of their aspect ratios, widths OR heights will really tend to output the undesirable results.

How to make 2 rows in horizontal collection view without using sections

The horizontal scrolling in UICollectionView only returns one row and I need to make a horizontal scrolling collection view with 2 rows just like the image below
[1]: https://i.stack.imgur.com/Vs1kt.png :[1]
You need to set fix height of the CollectionView and then use sizeForItemAt() under UICollectionViewDelegateFlowLayout which returns CGSize. You have to manage the cell height something like this.
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 50.0, height: collectionViewHeight / 2) //<-- Manage height and width accordingly.
}

How to align collectionview cells right next to each other?

I am creating a profile page screen for my application. The screen displays all the user's recent posts. I used storyboard to create two UICollectionViewCells in a UICollectionView, one that displays your profile info and the other that displays your posts. See this for how I designed it in storyboard: https://i.stack.imgur.com/6TzwK.png
When I run the application, I get the following result: https://i.stack.imgur.com/XmvY3.jpg
However, I desire the cells placed in a way that it looks like the following: https://i.stack.imgur.com/nWQ14.jpg
How do I force the cells the align so it looks like the image above? Thanks!
Found an answer to the question. Implement UICollectionViewDelegateFlowLayout delegate to your class. Then, include the following method into the class:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = UIScreen.main.bounds.width // get the width of the screen
let scale = (width / 3) // get the width (and height) of each cell
if indexPath.row != 0 { // check to see if the cell is the profile header
return CGSize(width: scale, height: scale) // if not, then return the cell size
}
return CGSize(width: width, height: ((238/414) * width)) // if it is the profile header, return the size for it.
}
Make sure "Min Spacing" for the UICollectionView's storyboard setting to 0,0. The cells will then align into a grid view.