How to make a collection view swipe to next item? [duplicate] - swift

This question already has answers here:
Snap to center of a cell when scrolling UICollectionView horizontally
(16 answers)
Closed last year.
I'm using a horizontal collection view to display various quotes which users can swipe to scroll through. It works fine, but the scroll is more like one long continuous scroll (like Instagram). I would like to change this to have each quote stop in the center of the screen and then the user to swipe again to go to the next quote (more like TikToc). How can I make this happen? I'm new to coding, so I'm not sure if there is a function for this. I tried the func ScrollToitem but don't know how to get it to implement this behavior.
import UIKit
class mainViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
#IBOutlet weak var checkcollectionview: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
checkcollectionview.dataSource = self
checkcollectionview.delegate = self
checkcollectionview.collectionViewLayout = UICollectionViewFlowLayout()
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
self.checkcollectionview.collectionViewLayout = layout
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return quotes.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = checkcollectionview.dequeueReusableCell(withReuseIdentifier: "check", for: indexPath) as! checkCollectionViewCell
cell.setup(with: quotes[indexPath.row])
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 700, height: 200)
}
}

As recommended by Andrew, I found a solution in a different post (link to solution below). The snap is nice and smooth.
https://stackoverflow.com/a/48572117/17152459

Related

UICollectionViewCell is not rounding corners inside UITableView

The problem is that when I have UICollectionView inside UITableViewCell - UICollectionViewCell cornerRadius function not working.
Code is very simple and it was always working for me when playing with UICollectionView.
extension ExploreTableViewCell: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! ExploreCollectionViewCell
cell.thumbnail.layer.cornerRadius = 20
cell.thumbnail.clipsToBounds = true
return cell
}
Is it a bug or what? Cannot find any answer all day. Most of the people suggest to use contentView instead of the specific image inside the cell but that's not for me since I want only image to be rounded.
P.S this one works (but I want only image inside the cell to be rounded):
override func awakeFromNib() {
super.awakeFromNib()
self.layer.cornerRadius = 30
self.clipsToBounds = true
}

Trying to Add a CollectionView to ResuableView Header like Instagram or SNapchat

I want to have a CollectionView in my Header that resembles that on Instagram and Snapchat for my main CollectionView which would be the feed. When I try to add the collectionview from the library and set the header as delegate and datasource after implementing the delegate methods, I still dont see anything in the header.
//let layout = UICollectionViewFlowLayout()
let headerCollection = UICollectionView(frame: CGRect(x: 0, y: 0, width: 50, height: 90), collectionViewLayout: UICollectionViewFlowLayout())
override func awakeFromNib() {
super.awakeFromNib()
// headerCollection.delegate = self
// headerCollection.dataSource = self
}
}
extension HeaderforFeed: UICollectionViewDataSource, UICollectionViewDelegate{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return CollectionViewData.Dict_StrImg.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = UICollectionViewCell(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
cell.backgroundColor = .red
return cell
}
}```
Based on your code, I would think that the issue is you are not adding it to the header (I understand it as a header section inside your UICollectionView). If it's so, try add it at
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
}
Here, you would add your custom view with UICollectionView as UICollectionReusableView
I don't know if this could help you, but according to your question is what I understood
its fine i figured it out. I added the collectionview from the library unto my header in storyboard. Then i connected it as an outlet in my UICollectionReusableView class. I then made that class implement the delegate methods for a collectionview but for the one in the header.
Make the reusableview the delegate and datasource and it worked for me
// HeaderforFeed.swift
// finishedFeednStories
//
// Created by Guh Suck Yu Mada
// Copyright © 2019 Bumboklat. All rights reserved.
//
import UIKit
class HeaderforFeed: UICollectionReusableView {
//let layout = UICollectionViewFlowLayout()
#IBOutlet weak var storiesCollection: UICollectionView!
override func awakeFromNib() {
super.awakeFromNib()
storiesCollection.delegate = self
storiesCollection.dataSource = self
}
}
extension HeaderforFeed: UICollectionViewDataSource, UICollectionViewDelegate{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return CollectionViewData.Dict_StrImg.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "storiesCell", for: indexPath) as! StoriesCell
cell.storiesImg.image = Array(CollectionViewData.Dict_StrImg)[indexPath.row].value
cell.storiesLabel.text = Array(CollectionViewData.Dict_StrImg)[indexPath.row].key
return cell
}
}

Why won't my Collection View Cells display in the iPhone Simulator?

I am trying to programmatically create a Collection View with six cells. The iPhone Simulator in Xcode 8 told me that my build was successful. There is still an error though.
Any help spotting the bug or bugs that are causing my cells not to display in the Simulator is greatly appreciated. (I put the Collection View directly into the IB from the Object Library. Also, I want each cell to occupy the entire size of the Collection View, hence displayedCellDimensions, because the user will segue between cells when a forward or backward button is tapped.) Thank you!
import UIKit
class FluidIntakeMainMenuViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
//MARK: - Collection View Properties
#IBOutlet weak var ibCollectionView: UICollectionView!
var cellArray:[customCollectionViewCell] = Array(repeating: customCollectionViewCell(), count: 6)
let displayedCellDimensions = CGSize(width: 343, height: 248)
//MARK: - Xcode-generated Methods
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
ibCollectionView.dataSource = self
ibCollectionView.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: - Collection View Methods
//Place cells in collection view and change the cell size
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
if collectionView.visibleCells.isEmpty {
for cell in 0...cellArray.count {
collectionView.addSubview(cellArray[cell])
return CGSize(width: 343, height: 248)
}
}
return CGSize(width: 343, height: 248)
}
//Register a new cell
func registerCell(_ collectionView: UICollectionView) {
for _ in 0...cellArray.count {
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "Cell")
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return cellArray.count
}
...}
In your viewDidLoad() Try:
viewDidLoad() {
ibCollectionView.dataSource = self
ibCollectionView.delegate = self
}
Add this to the top of your class:
class FluidIntakeMainMenuViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
You must use these functions in your ViewController class:
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {}

CollectionView Cell clicked expand new view

I'm trying to create a demo app that has a TabBarViewController as well as 4 tabs ( 4 Different ViewControllers on the storyboard)
On the first Tab which is the first ViewController, I have a collectionView
with Cells that have ImageView and few Labels.
What I'm trying to do is, when you click on a Cell, It expands to the whole screen, and the view still stays in the first Tab from the Tab Bar,
just now that the view inside the ViewController has changed to a new view that is an expanded view of the Cell that was selected, and when you scroll down the collection view continues, and you can click another cell and it expands and so on...while you can at any time press back and it shows the last cell that was expanded in the view
I hope I was clear enough about what I'm trying to do. now ill add the code of what I've got already
import UIKit
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
var imagesArray = []
var imageSizes = [CGSize]()
var labelsArray = [""]
var descArray = [""]
#IBOutlet weak var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
self.collectionView.delegate = self
self.collectionView.dataSource = self
for i in 0..<imagesArray.count {
let currImg = imagesArray[i]
let currHeight = currImg.size.height
let currSize = CGSize(width: 150, height: currHeight + 125)
imageSizes.append(currSize)
}
}
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return imagesArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionVCe
cell.cellImg.image = imagesArray[indexPath.row]
cell.descLabel.text = descArray[1]
cell.itemLabel.text = labelsArray[0]
cell.cellImg.contentMode = .scaleAspectFill
cell.layer.cornerRadius = 9
cell.backgroundColor = UIColor.red
cell.cellImg.backgroundColor = UIColor.blue
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return imageSizes[indexPath.row]
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsetsMake(0, 25, 0, 25)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 10
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if let cell = collectionView.cellForItem(at: indexPath) {
cell.frame = collectionView.frame
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
You have reload the collection view and also call size delegate of collection view

How do I change the size of a 2x2 UICollectionView and fit the whole screen: Swift 3 Xcode 8

Hi I am creating an app which requires a grid of images. As an example I am using a 2x2 grid of images in cells of a UICollectionView. I would like to know how I could decrease the annoying space in the middle and also make them have equal widths and heights to fit the whole screen. I know that I can do this with Interface builder. However, I want to do this programmatically because as the app progresses, there will be different levels and different number of squares - possibly a 10x10 also. I am new to UICollectionViews. I have referenced to many other questions, however most are in Objective C and there few that are in Swift don't seem to work with Swift 3.
Here is my full code:
import UIKit
class GameViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout{
#IBOutlet weak var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
collectionView.delegate = self
collectionView.dataSource = self
let collectionViewLayout = self.collectionView.collectionViewLayout as! UICollectionViewFlowLayout
collectionViewLayout.minimumLineSpacing = 0
collectionViewLayout.minimumInteritemSpacing = 0
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 2;
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 2
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
let image = cell.viewWithTag(1) as! UIImageView
image.image = #imageLiteral(resourceName: "coffee")
return cell;
}
func collectionView(_collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
return CGSize(width: self.collectionView.frame.size.width/2, height: self.collectionView.frame.size.height/2)
//this method is not getting called
}
}
I am also uploading an image of how it currently is and how I want it to be-
I hope you guys will help me- it will be very useful... Thanks!
I conformed to UICollectionViewDelegateFlowLayout and called sizeforitematindexpath but it did not work.
On adding a breakpoint I realized that the method was not getting called. So is there anything wrong I'm doing here. Also Xcode gives me this warning -
Make sure that:
Confirming to UICollectionViewDelegateFlowLayout.
collectionView's width = screen's width.
Min Spacing for cells is zero. You can change it from the Interface Builder (Select the collectionView -> show size inspector -> set min spacing to 0), or by implementing minimumInteritemSpacingForSectionAt returning zero.
If you want to fill the whole Screen height (I am asking because this is not what provided in your screenshot), collectionView's height = screen's height.
Finally, implement sizeForItemAtIndexPath method:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.frame.width / 2, height: 100)
}
Use following code in viewDidLoad
let collectionViewLayout = self.collectionView.collectionViewLayout as! UICollectionViewFlowLayout
collectionViewLayout.minimumLineSpacing = 0
collectionViewLayout.minimumInteritemSpacing = 0
collectionViewLayout.itemSize = CGSize(width: UIScreen.main.bounds.width/2, height: UIScreen.main.bounds.width/2)
Use "UICollectionViewDelegateFlowLayout" Delegate for set size for CollectionView cell size
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: UIScreen.main.bounds.width/2, height: UIScreen.main.bounds.width/2)
}
I hope this will helpfull for you.
You can use the following to size the cells:
extension GameViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let cellWidth = self.collectionView.bounds.width / 2
return CGSize(width: cellWidth, height: cellWidth)
}
}
Also, add the following lines at the end of viewDidLoad() to get rid of the unwanted white space:
let collectionViewLayout = self.collectionView.collectionViewLayout as! UICollectionViewFlowLayout
collectionViewLayout.minimumLineSpacing = 0
collectionViewLayout.minimumInteritemSpacing = 0