So im trying to filter my collectionview data using another collectionview, something like this
as from the picture on i try to make a filter button so i can filter the data base on the button that user tap, and the way im trying to make that filter button is to use another collectionview, but i dont know how to implement it.
so far here's my code :
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if collectionView == homeColView {
return homeVm.heroList.count
}else if collectionView == filterColView {
return homeVm.filterRoles.count
}
return 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView == homeColView{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "HomeCollectionCell", for: indexPath) as! HomeCollectionCell
let data = homeVm.heroList[indexPath.row]
let imgUrl = URL(string: BASE_URL + data.img)
cell.heroNameLabel.text = data.localized_name
cell.heroImage.kf.setImage(with: imgUrl)
return cell
}else if collectionView == filterColView {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FilterCollectionCell", for: indexPath) as! FilterCollectionCell
cell.filterLabel.text = homeVm.filterRoles[indexPath.row]
return cell
}
return collectionView.dequeueReusableCell(withReuseIdentifier: "HomeCollectionCell", for: indexPath) as! HomeCollectionCell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if collectionView == homeColView {
let vc = HeroDetailsVc()
vc.heroDetailsVm.heroDetails = homeVm.heroList[indexPath.row]
self.navigationController?.pushViewController(vc, animated: true)
collectionView.deselectItem(at: indexPath as IndexPath, animated: true)
}else if collectionView == filterColView {
}
}
can anyone help me how to make this filter with collectionview?
Thank you
Related
Using UICollectionView to display calendar, I have made today's date selected by default and want to deselect that when any other date selected. Below is my code:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CalenderCell", for: indexPath) as! CalenderCollectionViewCell
cell.lblDayName.text = arrCalendarDays[indexPath.item]
cell.lblDate.text = arrCalendarOnlyDate[indexPath.item]
if indexPath.item == 0 {
if !isTodayDate {
cell.isSelected = true
} else {
cell.isSelected = false
}
}
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
isTodayDate = true
// Tried below code but not working
/* collectionViewWeekCalendar.indexPathsForSelectedItems?
.forEach {
self.collectionViewWeekCalendar.deselectItem(at: $0, animated: false) }
*/
let selectedCell:UICollectionViewCell = collectionViewWeekCalendar.cellForItem(at: indexPath)!
selectedCell.isSelected = true
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
let selectedCell:UICollectionViewCell = collectionViewWeekCalendar.cellForItem(at: indexPath as IndexPath)!
selectedCell.isSelected = false
}
Problem is that, when selecting any other date, today's selected date is not getting deselect. Please guide.
the hacky and easiest way (i think)
use selected index
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CalenderCell", for: indexPath) as! CalenderCollectionViewCell
cell.lblDayName.text = arrCalendarDays[indexPath.item]
cell.lblDate.text = arrCalendarOnlyDate[indexPath.item]
if sellectedIndex == indexPath {
cell.isSelected = true
} else {
cell.isSelected = false
}
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
selectedIndex = indexPath
collectionView.reloadData()
}
and at the start,
set selectedIndex = today date Index
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
}
}
}
I am new to iOS and I want to implement a UICollectionView inside a UITableView which can have multiple select/unselect in section 1 of the UITableview. And in section 2, only a single selection is allowed. And save the selection sate event if I dismiss the Viewcontroller and when I open it again, it must show the last selected cell as highlight.
I searched for tutorials but all of them don't mention to select/unselect the state of collection cell or saving state after dismissing view controller.
Can someone help to implement it?
Thank in advance!
Here is my code I do till now:
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return clvData.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "clvCell", for: indexPath) as! demoCollectionViewCell
cell.title.text = clvData[indexPath.item] as? String
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath)
cell?.backgroundColor = .red
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath)
cell?.backgroundColor = .white
}
you guys can also check my project here:
https://mega.nz/#!xRs0EQyQ
try this and let me know if you have any problem or if this solved your problem.
var arrSelectedIndex:[IndexPath] = []// store this array either in database by api or in local
var clvData:[String] = []// your data array
//get the arrSelectedIndex from default in viewDidLoad before reloading the table and collection.
override func viewDidLoad() {
super.viewDidLoad()
if let myArray = UserDefaults.standard.array(forKey: "selectedArray") as? [IndexPath] {
arrSelectedIndex = myArray
} else {
arrSelectedIndex = []
}
}
// and save the arrSelectedIndex in viewWillDisappear method
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
UserDefaults.standard.set(arrSelectedIndex, forKey: "selectedArray")
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return clvData.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "clvCell", for: indexPath) as! demoCollectionViewCell
cell.title.text = clvData[indexPath.item] as? String
if arrSelectedIndex.contains(indexPath) { // You need to check wether selected index array contain current index if yes then change the color
cell.backgroundColor = UIColor.red
}
else {
cell.backgroundColor = UIColor.white
}
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath)
cell?.backgroundColor = .red
if !arrSelectedIndex.contains(indexPath) {// if it does not contains the index then add it
arrSelectedIndex.append(indexPath)
}
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath)
cell?.backgroundColor = .white
if let currIndex = arrSelectedIndex.firstIndex(of: indexPath) {// if it contains the index then delete from array
arrSelectedIndex.remove(at: currIndex)
}
}
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
}
}
I have a UICollectionView which uses custom xib file for it's cells. In the cell I have an ImageView for check box. I want to change the image of the `ImageView1 when it was taped. I tried the following code snippet but, it's not working for me
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! V_Cell
if show_delete == true {
cell.img_delete.image = UIImage(named: "checked")
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! V_Cell
// Configure the cell
let data = valves_[indexPath.row]
cell.v_name.text = data
if show_delete == true {
cell.img_delete.isHidden = false
} else if show_delete == false {
cell.img_delete.isHidden = true
}
return cell
}
In this code I've tried to change the image of ImageView in didSelectItemAt.
My custom xib file is as following.
Please suggest a way to make it work. Thanks.
For these kind of problems, it is always better to keep an array which contains whether an item at a given indexpath is checked or not.
var checkArray: [Bool] = [Bool](repeating: false, count: numberOfRowsInCollectionView)
// this should be the same size as number of items in collection view
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! V_Cell
checkArray[indexPath.row] = !checkArray[indexPath.row] // if it's true, make it false and vice versa logic
collectionView.reloadItems(at: [indexPath])
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! V_Cell
// Configure the cell
let data = valves_[indexPath.row]
cell.v_name.text = data
if show_delete == true {
cell.img_delete.isHidden = false
} else if show_delete == false {
cell.img_delete.isHidden = true
}
if checkArray[indexPath.row] {
cell.img_delete.image = //image for check
}else {
cell.img_delete.image = //image for no check
}
return cell
}
Finally I solved it by the following code.
var checkArray = [Int]()
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if show_delete == true {
if checkArray.contains(indexPath.row) {
let index = checkArray.index(of: indexPath.row)
checkArray.remove(at: index!)
collectionView.reloadItems(at: [indexPath])
} else {
checkArray.append(indexPath.row)
collectionView.reloadItems(at: [indexPath])
}
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! V_Cell
// Configure the cell
let data = valves_[indexPath.row]
cell.v_name.text = data
if show_delete == true {
cell.img_delete.isHidden = false
} else if show_delete == false {
cell.img_delete.isHidden = true
}
if checkArray.contains(indexPath.row) {
cell.img_delete.image = UIImage(named: "checked_n")
} else {
cell.img_delete.image = UIImage(named: "unchecked")
}
return cell
}
I put taped element indexes in an array and reloaded the items at indexpath. if the array contains the reloaded index then it displays the check mark, if not it removes the check mark.