Fitting all items into one collection view row - swift

Is there a way to make all items in a collection view fit in one row and not automatically place items in an another row? I'm trying to copy something like Instagram's story display like the link below:
However, In my collection view, I'm getting a count from a server, and displaying the information in a collection view but it always goes to the next line after 3 items are displayed.
// number of sections function
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return pictures.count
} // end of function

I think you don't want Vertical scrolling in Collection view.
For horizontal scrolling in collection view, select collection view in storyboard and change scroll direction to horizontal.
Refer this below pic:

you can add collectionViewLayout delegate method like this. CGFloat(3.0) is how many item you want, you have to divide it from collectionView's width
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let itemWidth: CGFloat = ((collectionView.bounds.size.width) / CGFloat(3.0))
return CGSize(width: itemWidth, height: collectionView.bounds.size.height)
}

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.

Collection cell wrongly resized in reloadData

I don't know why but the cells of my collectionView are automatically wrongly resized after a reloadData.
After first init, then after reloadData :
I'm using UICollectionViewDelegateFlowLayout to define the size of the cell but it don't take care of it :
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
let paddingSpace = sectionInsets.left * (2 + 1)
let availableWidth = view.frame.width - paddingSpace
let widthPerItem = availableWidth / 2
return CGSize(width: widthPerItem, height: widthPerItem)
}
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
insetForSectionAt section: Int) -> UIEdgeInsets {
return sectionInsets
}
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return sectionInsets.left
}
When execution come in the cellForItemAt, the cell have the right size, the shadow is created in this function and it have the right width.
One last thing is that only the width is resized, the height stay as I want.
Does any one have an idea why the width is resized wrongly after the reloadData ?
I was having a similar issue when making an extension of the UICollectionViewDelegateFlowLayout and it turns out that setting the collectionView's Estimated Size to "None" in the storyboard (Size Inspector) solved it.
As stated in the Xcode 11 Release Notes:
Cells in a UICollectionView can now self size with Auto Layout
constrained views in the canvas. To opt into the behavior for existing
collection views, enable “Automatic” for the collection view’s
estimated size, and “Automatic” for cell’s size from the Size
inspector.
If deploying before iOS 13, you can activate self sizing collection
view cells by calling performBatchUpdates(_:completion:) during
viewDidLoad(). (45617083)
So, newly created collectionViews have the attribute "Estimated Size" set as "Automatic" and the cell's size is computed considering its subview dimensions, thus ignoring the UICollectionViewDelegateFlowLayout extension methods, even though they are called.

Horizontal collection view with different height of cells

I am trying to do some horizontal collection view with dynamic height of each cell. Like citymapper does when you have aready choosen a trip. ¿Has anyone got any idea of how to do this? Even though if it's not with a collection view.
Video of the behaviour
One way of doing this is implementing the UICollectionViewDelegateFlowLayout of the collectionView.
One of the methods of this delegate is final public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize. Here you can return the size of the collectionCell depending on the content or whatever you use to determinate the height.
Hope it helps.

How to tap on item in one controller and have it show in a different uicollectionviewcontroller class

I'm trying to tap on a collection view cell in one collection view controller and have it dynamically added to another collection view controller on same screen that when filled will turn into horizontal scrolling list of items. Similar to what is seen in the attached image of chickfila app when wanting to add pickles or bacon to order..
I have two different collection view controllers, one for the horizontal effect, shown on top of screen, and another controller showing the items that can be selected below. When I tap on items below I think I can get the array appended, but despite all kinds of reloadData calls, I can't get it to show this item in the horizontal controller above.. It doesn't seem to be calling didSelectItemAt again no matter what I do. I'm trying to do this just using the didSelectItemAt method.
Am I going about this totally wrong perhaps? I'm relatively new to the world of iOS programming. Thanks for any suggestions or help!!
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("tapped to add extra item somehow..")
let selectedItem = indexPath.item
if selectedItem >= 0 && indexPath.item < extras.count {
super.extras.append(Extras(imageName: "bacon", calories: 100, price: 1, quantity: 1))
}
indexPath.index only gives you the index number in an array of element, and not the element(object) you are looking for.
You might wanna try something like this:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print(arrayHoldingYourObjects[indexPath.item].id)
collector.append(arrayHoldingYourObjects[indexPath.item])
print("This is your colector \(collector)")
}
var collector: [Any] = []

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.
}