How to use multiple arrays of items in one collectionView? - ios

I have one UICollectionView in my UIView. What I'm trying to do is when user press the button then other items(images array) appear on same UICollectionView.
Let's say I have two arrays of items:
let items = [UIImage(named: "moses-vega-436582-unsplash"),
UIImage(named: "april6"), UIImage(named: "april4"), UIImage(named:
"april5")]
let items2 = [UIImage(named: "test01"), UIImage(named: "test02")]
Now when user press the button I want to update my collectionView with images from items2. I'm using basic code for collections (it's easy for me to detect which labels for example to show. Because I have variable called "Testas" and if it's 0 then I know that it's default collectionView and else it's .... :
func collectionView(_ collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return items.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
if Testas == 0 {
cell.image.image = items[indexPath.item]
if indexPath.item == 0 {
cell.label.text = "One"
}
if indexPath.item == 1 {
cell.label.text = "Two"
}
if indexPath.item == 2 {
cell.label.text = "Collection 3"
}
if indexPath.item == 3 {
cell.label.text = "Rainy Days"
}
} else {
cell.image.image = items2[indexPath.item]
if indexPath.item == 0 {
cell.label.text = "White"
}
if indexPath.item == 1 {
cell.label.text = "Blue"
}
}
return cell
}
In conclusion, I'm asking what I need to write to pass items2 into collectionView when the user press the button and how to make this collectionView appear? (because it's not a function or something what I could call easily I guess). Keep in mind that I have a function where it counts items. So that's the biggest problem. I need a function to count my items2 when user press the button and then make images appear.
Thank you so much. Maybe it's not even possible to make what I want this way. I don't know.

You could accomplish this easily by creating an enum, and then simply toggling it's value when the button is pressed followed by a collectionView.reloadData()
Here is your enum:
enum ItemType : Int {
case items = 0,
items2 = 1
}
Declare it like this:
var itemType : ItemType = .items
Your collectionView functions would look something like this:
func collectionView(_ collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return itemType == .items ? items.count : items2.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
switch itemType {
case .items:
// code for items array
default:
// code for items2 array
}
return cell
}
Your button press:
#IBAction func onButtonPressed(_ sender: Any) {
itemType = .items2
collectionView.reloadData()
}
If you have more than 2 arrays you will need to update your collectionView functions to something like this:
func collectionView(_ collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
switch itemType {
case .items:
return items.count
case .items2:
return items2.count
case .items3:
return items3.count
default:
return items4.count
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
switch itemType {
case .items:
// code for items array
case .items2:
// code for items2 array
case .items3:
// code for items3 array
default:
// code for items4 array
}
return cell
}

Related

How can I manage two different cells in numberofitemsinsection

I want to create a collectionView with two different cells. The first cell should be displayed one time and the second should be displayed as often as the array is large. The result should be something like in the image in the attached link. Here is also a example code for better understanding my problem. Thanks to everyone who helps me!!! 🙂
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
switch indexpath { // No indexpath in numberofitemsinsection!
case 0:
return 1 //display one time the first cell
default:
return images.count // display as often as the array is large the second cell
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
switch indexPath.row {
case 0:
let cell = imageCollectionView.dequeueReusableCell(withReuseIdentifier: "addImageCell", for: indexPath)
return cell
default:
let cell = imageCollectionView.dequeueReusableCell(withReuseIdentifier: "imageCell", for: indexPath) as! ImageCell
cell.imageView.image = images[indexPath.row]
cell.delegate = self
cell.selectedAtIndex = indexPath
return cell
}
}
Here is the collectionView I want to create
You can achieve this inside cellForItemAt and you need to change numberOfItemsInSection like below:
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// return 1 more than our data array (the extra one will be the "add item" cell)
return dataSourceArray.count + 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// if indexPath.item is less than data count, return a "Content" cell
if indexPath.item < dataSourceArray.count {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ContentCell", for: indexPath) as! ContentCell
// configure your ContentCell: cell. <attribute>
return cell
}
// past the end of the data count, so return an "Add Item" cell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "AddItemCell", for: indexPath) as! AddItemCell
// configure your AddCell: cell. <attribute>
return cell
}
For that you need to create a ContentCell and AddItemCell and also have a dataSourceArray to store all data you need.
Why don't you use this?
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1 + theArray.count
}

Swift CollectionView first cell add user button and other cell load from image array

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.

Two different collection views getting the item count of the other

I have an app with 2 different arrays that usually have 2 different item counts. For some reason the first collection view is getting the item count of the second collection view unless I get rid of the second collection view.
My code:
<script src="https://pastebin.com/embed_js/NAtgb3kp"></script>
Steps:
1. say your collection are
var albumsViewCollectionView, songsViewCollectionView : UICollectionView!
Register the nib files for your 2 collectionviews
your collectionview datasource method
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if collectionview == albumsViewCollectionView {
return albumCount
}
else if collectionview == songsViewCollectionView {
return songsCount
}
return 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView == albumsViewCollectionView {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "AlbumsViewCollectionView", for: indexPath) as! AlbumsViewCollectionView
return cell
}
else if collectionView == songsViewCollectionView {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SongsViewCollectionView", for: indexPath) as! SongsViewCollectionView
return cell
}
return UICollectionViewCell()
}

Deque custom cells from specific indexpath SWIFT

I have UICollectionView, I am downloading images and displaying them in the cells. My first cell is of screen width and contains a button, rest are the general cells. The application only deques the first 2 cells, There are supposed to be 3 cells.
My cellForItemAtIndexPath function:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if indexPath.row == 0 {
print("yay")
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "UploadNewCell", for: indexPath) as! UploadNewCell
return cell
}else if indexPath.row > 0 {
let userImages = userposts[indexPath.row]
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ProfileCell", for: indexPath) as! ProfileCell
cell.fillCells(uid: uid!, userPost: userImages)
return cell
}else{
return ProfileCell()
}
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if indexPath.row == 0 {
print("hellowold")
} else {
let selecteditem : String!
selecteditem = userposts[indexPath.row]
performSegue(withIdentifier: "lol", sender: selecteditem)
}
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return userposts.count
}
my view:
There are supposed to be 3 images down there in the cells, One of them is dequed in the first index.
I am out of Ideas, Any ideas on the solution?
let userImages = userposts[indexPath.row]
At this point in your code, indexPath.row is > 0.
Arrays are 0-based, so the first cell (indexPath.row == 1) is getting the second item in your array (user posts[1]), which is the second image you wanted.
I can think of a couple of simple changes:
Change the index you're accessing, such as:
let userImages = userposts[indexPath.row - 1]
Add 1 to your userposts.count value in numberOfItemsInSection:
Split your collectionView into having multiple sections, so the top cell (UploadNewCell) is section 0, and the bottom three ProfileCells are a second section: this allows you to check the indexPath.section, and assign directly from row:
let userImages = userposts[indexPath.row]
Note: I would actually advise further modifying the code for the second option to create an enum for SectionType. That allows you to perform a switch over the potential values, allowing you to avoid that nasty default implementation, and boosts the readability of your code.

Adding new Item to CollectionView programmatically, via the last Item

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

Resources