I am working on an existing project which has a collectionView, right now i want to add another collectionView in this same viewcontroller. Already tried different solutions but can not seem to have any luck. Here is the existing code for collectionview:
func numberOfSections(in collectionView: UICollectionView) -> Int {
if homeList.last?.catList.isEmpty ?? false{
return homeList.count - 1
}
return self.homeList.count
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if section == homeList.count - 1{
return 2
}
return homeList[section].catList.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if indexPath.section == homeList.count - 1{
let doctorsCell = collectionView.dequeueReusableCell(withReuseIdentifier: "doctorCell", for: indexPath) as! DoctorsCVC
doctorsCell.docDelegate = self
doctorsCell.docList = homeList[indexPath.section].catList as? [Doctor] ?? []
delayOnMain(0.1){
doctorsCell.docCollectionView.reloadData()
}
return doctorsCell
}
else{
let productsCell = collectionView.dequeueReusableCell(withReuseIdentifier: "productCell", for: indexPath) as! ProductCVC
productsCell.setData(homeList[indexPath.section].catList[indexPath.row])
productsCell.fivePercentView.layer.cornerRadius = 5
return productsCell
}
}
And here is my new code for collectionView:
#IBOutlet var collectionView2: UICollectionView!
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return arrData.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionViewCell
cell.img.image = arrData[indexPath.row].image
return cell
}
Can someone help me to merge this code!
What I think is a clearer method is to use a second collectionViewController and a custom container view controller.
That way, the differentiation in the delegate methods is no longer needed.
You can't use two same collectionView delegate methods (eg -cellForItemAt ) methods in same view controller. So you have to check the collection view inside every collectionView delegate methods.
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if collectionView == self.collectionView2 {
return arrData.count
} else {
if section == homeList.count - 1 {
return 2
}
return homeList[section].catList.count
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView == self.collectionView2 {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionViewCell
cell.img.image = arrData[indexPath.row].image
return cell
}else{
if indexPath.section == homeList.count - 1{
let doctorsCell = collectionView.dequeueReusableCell(withReuseIdentifier: "doctorCell", for: indexPath) as! DoctorsCVC
doctorsCell.docDelegate = self
doctorsCell.docList = homeList[indexPath.section].catList as? [Doctor] ?? []
delayOnMain(0.1){
doctorsCell.docCollectionView.reloadData()
}
return doctorsCell
}
else{
let productsCell = collectionView.dequeueReusableCell(withReuseIdentifier: "productCell", for: indexPath) as! ProductCVC
productsCell.setData(homeList[indexPath.section].catList[indexPath.row])
productsCell.fivePercentView.layer.cornerRadius = 5
return productsCell
}
}
}
Related
I have 2 arrays with different data
var array : [String] = ["getMeals", "getMeasure", "getWorkouts"]
var array2 : [String] = ["getStep", "getStep", "getStep"]
I am trying to retrieve the images from arrays, but in different collection cells.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if indexPath.section == 0{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "WorkoutCollectionCell", for: indexPath) as! WorkoutCollectionCell
cell.collectionImage.image = UIImage(named: array[indexPath.row])
return cell
}else{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "WorkoutCollectionCell", for: indexPath) as! WorkoutCollectionCell
cell.collectionImage.image = UIImage(named: array2[indexPath.row])
return cell
}
}
I need to create another UICollectionViewCell or I can use the current cell?
you can use the same cell, with this code:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "WorkoutCollectionCell", for: indexPath) as! WorkoutCollectionCell
if indexPath.section == 0{
cell.collectionImage.image = UIImage(named: array[indexPath.row])
}else{
cell.collectionImage.image = UIImage(named: array2[indexPath.row])
}
return cell
}
You need 1 array like
let array = [["getMeals", "getMeasure", "getWorkouts"],["getStep", "getStep", "getStep"]]
func numberOfSections(in collectionView: UICollectionView) -> Int {
return array.count
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return array[section].count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "WorkoutCollectionCell", for: indexPath) as! WorkoutCollectionCell
cell.collectionImage.image = UIImage(named: array[indexPath.section][indexPath.row])
return cell
}
In my case, I am trying to create a UICollcetionView with first cell add button for add user and from second cell I need to load Image array string into another cells. Here, I am using two separate cell but I am not getting first cell into my output. Please provide me solution or another best method.
I am trying to get below output
Multiple Cell Code
// MARK: CollectionView Delegate
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 2
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return imageArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if indexPath.section == 0 {
let firstCell = collectionView.dequeueReusableCell(withReuseIdentifier: "addusercell", for: indexPath) as! AddParticipantsCollectionViewCell
return firstCell
} else {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "userscollectionview", for: indexPath as IndexPath) as! ParticipantsCollectionViewCell
cell.imageView?.image = self.imageArray[indexPath.row]
return cell
}
}
You need
if indexPath.item == 0 {
// first cell
}
else {
// second cell
cell.imageView?.image = self.imageArray[indexPath.item - 1]
}
Correct dataSource method ( remove it )
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1 // Section should set return 1 or default is optional
}
And change numberOfItemsInSection to
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return imageArray.count + 1
}
If you have two sections in the collectionView you also need to set the number of items in each individual section:
// MARK: CollectionView Delegate
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 2
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if section == 0 {
return 1 // return 1 item in cell (+ cell)
} else {
return imageArray.count
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if indexPath.section == 0 {
let firstCell = collectionView.dequeueReusableCell(withReuseIdentifier: "addusercell", for: indexPath) as! AddParticipantsCollectionViewCell
return firstCell
} else {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "userscollectionview", for: indexPath as IndexPath) as! ParticipantsCollectionViewCell
cell.imageView?.image = self.imageArray[indexPath.row]
return cell
}
}
I hope it's been of any help.
My code below would work if it was displayed on a label. But in this function I am getting the error message Missing return in a function expected to return 'UICollectionViewCell'. Putting the return cell in the for loop does not work.
import UIKit
class collectionVIEW: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
var users = [User]()
#IBOutlet var theIssues: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
// users = cdHandler.fetchObject()!
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return users.count
}
func getDefaultCell() -> UICollectionViewCell{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! whyCollectionViewCell
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if cdHandler.fetchObject() != nil {
users = cdHandler.fetchObject()!
for c in users {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! whyCollectionViewCell
cell.general.text = "\((cell.general.text)!)+\((c.userName)!)"
return cell
}
} else {
return getDefaultCell()
}
}
}
cellForItemAt method expects to return UICollectionViewCell in all cases. In the else condition, return a default cell as below:-
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if cdHandler.fetchObject() != nil {
users = cdHandler.fetchObject()!
for c in users {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! whyCollectionViewCell
cell.general.text = "\((cell.general.text)!)+\((c.userName)!)"
return cell
}
}else{
return getDefaultCell()
}
Note:-Register collection view with identifier defaultCcell
func getDefaultCell() -> UICollectionViewCell{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "defaultCcell", for: indexPath) as! UICollectionViewCell
return cell
}
I am unable to display the second cell despite registering it to the collectionView. Does anyone know why this is the case? The cell exists as when I switch the row the other cell displays instead.
class ViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
override func viewDidLoad() {
super.viewDidLoad()
collectionView?.backgroundColor = UIColor.white
collectionView?.register(HeaderCell.self, forCellWithReuseIdentifier: "HeaderCell")
collectionView?.register(SummaryCell.self, forCellWithReuseIdentifier: "SummaryCell")
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if section == 0 {
return 1
}
return 1
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if (indexPath.row == 0) {
let cell1 = collectionView.dequeueReusableCell(withReuseIdentifier: "HeaderCell", for: indexPath) as! HeaderCell
return cell1
} else {
let cell2 = collectionView.dequeueReusableCell(withReuseIdentifier: "SummaryCell", for: indexPath) as! SummaryCell
return cell2
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width, height: 200)
}
}
I have looked a this but still unable to get it to work.
P.S. I am programming everything programmatically.
You have registered 2 cells but you are returning only 1 row.Try returning 2 items.
//numberOfItemsInSection
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int{
return 2
}
None of the answer correctly/completely solves the issue. However I did use some of the suggestions to get it to work properly by adding the following:
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 2
}
And changing indexPath.row to indexPath.section
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if (indexPath.section == 0) {
let cell1 = collectionView.dequeueReusableCell(withReuseIdentifier: "HeaderCell", for: indexPath) as! HeaderCell
return cell1
} else {
let cell2 = collectionView.dequeueReusableCell(withReuseIdentifier: "SummaryCell", for: indexPath) as! SummaryCell
return cell2
}
}
I'm facing an issue with CollectionView, I want to see a collection of images and have an add button as the last item so first of all I've made an array of NSData as I'm gonna save those images to Core Data
var photoArray = [NSData]()
then I implement UICollectionViewDataSource
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if indexPath.item == photoArray.count + 1 {
present(imagePicker, animated: true, completion: nil)
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return photoArray.count + 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "photoItem", for: indexPath) as? PhotoCell else {return UICollectionViewCell()}
cell.btn.tag = indexPath.item
if indexPath.item == photoArray.count + 1 {
cell.thumImage.image = UIImage(named: "add_button")
cell.btn.isHidden = true
print("first")
return cell
} else {
let img = photoArray[indexPath.item]
cell.configureAddingImage(img: img)
print("second")
return cell
}
}
Actually I'm facing with the problem in "cellForItemAt indexPath" like "fatal error: index is out of range" I tried to make array look like var photoArray: [NSData]! but it caused other problems, please give me any advice or help, thank you!
Index is out of range because items or rows are indexed from 0
Should be like this:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "photoItem", for: indexPath) as? PhotoCell else {return UICollectionViewCell()}
cell.btn.tag = indexPath.row
if indexPath.row == photoArray.count {
cell.thumImage.image = UIImage(named: "add_button")
cell.btn.isHidden = true
print("first")
return cell
} else {
let img = photoArray[indexPath.row]
cell.configureAddingImage(img: img)
print("second")
return cell
}
}