passing values from uitableview to uicollectionview - ios

How can I pass parsed values from a url which has been used in an UITableview to a UICollectionview(scrolled horizontally) which has been used in each of the UITableviews cell? I want do this in swift language.
I am using a model with the name "collectionCat".
import Foundation
public class CollectionCat{
var brandid:String = ""
var brandname:String = ""
var result:String = ""
var noitems:String = ""
}
I am also using Alamofire to parse data from url.
override func viewDidLoad() {
super.viewDidLoad()
self.startActivityAnimating(message: "", type: NVActivityIndicatorType.BallClipRotate, color: AppColor.AppRed, padding: 10)
Alamofire.request(.POST, "http://goringr.co.in/Mathrubhumi_project_ios/brand.php", parameters: ["": ""])
.validate()
.responseJSON { response in
switch response.result {
case .Success:
print("Validation Successful")
self.jsonResultParse(response.result.value!)
self.stopActivityAnimating()
case .Failure(let error):
print(error)
self.stopActivityAnimating()
// return userCatagory
}
}
// Do any additional setup after loading the view.
}
if JSONArray.count != 0 {
//_ = [UserCatagory]()
for i:Int in 0 ..< JSONArray.count {
let jObject = JSONArray[i] as! NSDictionary
let uCollect:CollectionCat = CollectionCat()
uCollect.brandid = (jObject["brandid"] as AnyObject? as? String) ?? ""
uCollect.brandname = (jObject["brandname"] as AnyObject? as? String) ?? ""
uCollect.result = (jObject["result"] as AnyObject? as? String) ?? ""
uCollect.noitems = (jObject["noitems"] as AnyObject? as? String) ?? ""
collect.append(uCollect)
print("collect COUNT ",collect.count)
}
self.newTable.reloadData()
}
}
What i dont know is how to transfer the stored data to UICollection view which is in each cell of the mentioned UITableview.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// collectMaster = collect[indexPath.row]
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! SecondHomeViewCell
// collectMaster = CollectionCat()
cell.get = ????
return cell
}
Can anyone Please help me with this?
The SecondHomeViewCell's code goes like this.
import UIKit
import Kingfisher
import Alamofire
import NVActivityIndicatorView
class SecondHomeViewCell: UITableViewCell{
#IBOutlet weak var collectionView: UICollectionView!
var genre:CollectionCat? = nil{
didSet {
collectionView.reloadData()
}
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
//return genre!.brandid
// return genre
return 1
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("secondHome", forIndexPath: indexPath) as! SecondHomeCollectionViewCell
if let genre = genre {
cell.genre = genre.brandid[indexPath.row]
}
return cell
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
let itemsPerRow:CGFloat = 4
let hardCodedPadding:CGFloat = 5
let itemWidth = (collectionView.bounds.width / itemsPerRow) - hardCodedPadding
let itemHeight = collectionView.bounds.height - (2 * hardCodedPadding)
return CGSize(width: itemWidth, height: itemHeight)
}
}

Add a array in your ViewController, call it
var collCat = [CollectionCat]()
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let collectMaster = collCat[indexPath.row]
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! SecondHomeViewCell
cell.brandID = collectMaster.brandid
//and so on
return cell
}
If this is not the answer you are looking for, please tell me. Because I wanted to clarify but I don't have the ability to comment yet. I need to reach 50 reputation to be able to comment and ask some clarifications.

You can pass data to collection view by creating function in UITableviewCell custom class
class SecondHomeViewCell: UITableViewCell{
//Array containing modals for particular tableview cell index path
var arrDataFromViewController = NSArray()
func getData(arrData:NSArray){
arrDataFromViewController = arrData
collectionView.delegate = self
collectionView.dataSource = self
collectionView.reloadData()
}
#IBOutlet weak var collectionView: UICollectionView!
var genre:CollectionCat? = nil{
didSet {
collectionView.reloadData()
}
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
//return genre!.brandid
// return genre
return 1
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("secondHome", forIndexPath: indexPath) as! SecondHomeCollectionViewCell
if let genre = genre {
cell.genre = genre.brandid[indexPath.row]
}
return cell
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
let itemsPerRow:CGFloat = 4
let hardCodedPadding:CGFloat = 5
let itemWidth = (collectionView.bounds.width / itemsPerRow) - hardCodedPadding
let itemHeight = collectionView.bounds.height - (2 * hardCodedPadding)
return CGSize(width: itemWidth, height: itemHeight)
}
}
//Now in tableview data source method
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// collectMaster = collect[indexPath.row]
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! SecondHomeViewCell
// collectMaster = CollectionCat()
cell.getData = yourArray[indexPath.row]//Get Array data
return cell
}

Related

Get TableviewCells to display different data that is extracted from firebase and show them in CollectionView

I have this two structs, the data I am getting from a Firebase Database and I don't know how to get each tableview cell to display a different collection view, I have both cells (TableviewCell and CollectionViewCell) in xib Files but can't get them the way I want it to.
I have attached my ViewController where they are both in and the TableViewCell class. Please help
struct Clothes {
var price: Double
var imgClUrl: String
var id: String
var isActive: Bool = true
var timeStamp: Timestamp
var stock: Double
var name: String
init(data : [String : Any]) {
self.price = data["price"] as? Double ?? 0
self.imgClUrl = data["imgClUrl"] as? String ?? ""
self.id = data["id"] as? String ?? ""
self.isActive = data["isActive"] as? Bool ?? true
self.timeStamp = data["timeStamp"] as? Timestamp ?? Timestamp()
self.stock = data["stock"] as? Double ?? 0
self.name = data["name"] as? String ?? ""
}
}
struct TypesOfCLothing {
var title : String
var id : String
var clothes : [Clothes]
init (data : [String : Any]){
self.title = data["title"] as? String ?? ""
self.id = data["id"] as? String ?? ""
self.clothes = data["Clothes"] as! [Clothes]
}
}
class eachStoreTableViewCell: UITableViewCell{
#IBOutlet weak var eachRowCollView: UICollectionView!
#IBOutlet weak var eachRowLbl: UILabel!
var clothes = [Clothes]()
override func awakeFromNib() {
super.awakeFromNib()
eachRowCollView?.reloadData()
eachRowCollView?.delegate = self
eachRowCollView?.dataSource = self
self.eachRowCollView?.register(UINib(nibName: "RowColectionView", bundle: nil), forCellWithReuseIdentifier: Identifiers.ClothesCell)
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
func configureCell(clothingType: TypesOfCLothing) {
eachRowLbl?.text = clothingType.title}}
extension eachStoreTableViewCell: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return clothes.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Identifiers.ClothesCell, for: indexPath) as? RowColectionView{
cell.configureCell(clothes: clothes[indexPath.item])
return cell
}
return UICollectionViewCell()
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 160, height: 180)
}
class EachStoreVC: UIViewController {
#IBOutlet weak var StoreTblView: UITableView!
var typesOfClothing = [TypesOfCLothing]()
var tienda: Tiendas!
let db = Firestore.firestore()
var listener : ListenerRegistration!
override func viewDidLoad() {
super.viewDidLoad()
// StoreTblView?.delegate = self
// StoreTblView?.dataSource = self
StoreTblView?.register(UINib(nibName: "eachStoreTblViewCell", bundle: nil), forCellReuseIdentifier: Identifiers.ClothingTypeCell)
StoreTblView?.cellLayoutMarginsFollowReadableWidth = false
}
override func viewDidAppear(_ animated: Bool) {
}
override func viewDidDisappear(_ animated: Bool) {
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}}
extension EachStoreVC : UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return typesOfClothing.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: Identifiers.ClothingTypeCell, for: indexPath) as? eachStoreTableViewCell {
cell.configureCell(clothingType: typesOfClothing[indexPath.row])
cell.frame = CGRect(x: 0, y: 0, width: StoreTblView.frame.size.width, height: cell.frame.size.height)
return cell
}
return UITableViewCell()
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 200
}}
EDIT
The collectionView and Tableview now show fine but I'm having trouble getting the data from firebase, I have an array of document references inside each TypesOfClothing document, the code is as follows. I have also updated my 2 Structs.
func getRowData(){
listener = db.collection("TypesOfClothing").addSnapshotListener({ (snap, error) in
if let error = error {
debugPrint(error.localizedDescription)
return
}
snap?.documentChanges.forEach({ (change) in
let data = change.document.data()
let typesOfClothing = TypesOfCLothing.init(data: data)
switch change.type {
case.added:
self.onDocumentAdded(change: change, category: typesOfClothing)
case.modified:
self.onDocumentModified(change: change, category: typesOfClothing)
case.removed:
self.onDocumentRemoved(change: change)
}
})
}) }
func onDocumentAdded(change: DocumentChange, category: TypesOfCLothing){
let newIndex = Int(change.newIndex)
typesOfClothing.insert(category, at: newIndex)
StoreTblView?.insertRows(at: [IndexPath(row: newIndex, section: 0)], with: UITableView.RowAnimation.left)
}
func onDocumentModified(change: DocumentChange, category: TypesOfCLothing){
if change.newIndex == change.oldIndex {
let index = Int(change.newIndex)
typesOfClothing[index] = category
StoreTblView?.reloadRows(at: [IndexPath(row: index, section: 0)], with: UITableView.RowAnimation.left)
} else {
let oldIndex = Int(change.oldIndex)
let newIndex = Int(change.newIndex)
typesOfClothing.remove(at: oldIndex)
typesOfClothing.insert(category, at: newIndex)
StoreTblView?.moveRow(at: IndexPath(row: oldIndex, section: 0), to: IndexPath(row: newIndex, section: 0))
}
}
func onDocumentRemoved(change: DocumentChange){
let oldIndex = Int(change.oldIndex)
typesOfClothing.remove(at: Int(oldIndex))
StoreTblView?.deleteRows(at: [IndexPath(row: oldIndex, section: 0)], with: UITableView.RowAnimation.fade)
}
Struct use like this:
struct TypesOfClothing {
var title : String
var clothes: [Clothes]
}
struct Clothes {
var price: Double
var imgClUrl: String
var id: String
var isActive: Bool = true
var timeStamp: Timestamp
var stock: Double
var name: String
}
in Main View controller: try code like this:
var typesOfClothing: [TypesOfClothing] = []
in numberOfRowsInSection
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return typesOfClothing.count
}
in cellForRowAt
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: Identifiers.ClothingTypeCell, for: indexPath) as? eachStoreTableViewCell {
if indexPath.row < typesOfClothing?.count ?? 0 {
let cellData = typesOfClothing?[indexPath.row]
cell.configureCell(cellData)
}
return cell
}
return UITableViewCell()
}
in UITableViewCell class try like this:
class eachStoreTableViewCell: UITableViewCell{
#IBOutlet weak var eachRowCollView: UICollectionView!
#IBOutlet weak var eachRowLbl: UILabel!
var clothes = [Clothes]()
override func awakeFromNib() {
super.awakeFromNib()
eachRowCollView?.delegate = self
eachRowCollView?.dataSource = self
self.eachRowCollView?.register(UINib(nibName: "RowColectionView", bundle: nil), forCellWithReuseIdentifier: Identifiers.ClothesCell)
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
func configureCell(_ clothingType: TypesOfClothing) {
eachRowLbl?.text = clothingType.title
clothes = clothingType.clothes
eachRowCollView?.reloadData()
}
}
extension eachStoreTableViewCell: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return clothes.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Identifiers.ClothesCell, for: indexPath) as? RowColectionView{
cell.configureCell(clothes: clothes[indexPath.item])
return cell
}
return UICollectionViewCell()
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 160, height: 180)
}
}
it'll help you.
You can make one structs for load tableView Data
struct ClothingData
{
var typesOfClothing : String = ""
var clothes : [Clothes] = []
}
Load this structArray for tabelView
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return ClothingData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: Identifiers.ClothingTypeCell, for: indexPath) as? eachStoreTableViewCell
let row = ClothingData[indexPath.row]
cell.eachRowLbl?.text = row.typesOfClothing
cell.clothes = row.clothes
// Here you can pass clothesList to tabelViewCell for load collectionView
return cell
}

want to add a collectionView inside tableView by downloading data from firebase to show . ios App Swift

want to add a UICollectionView inside UITableView by downloading data from firebase to show
Now I'm done with the interface part, but I'm stuck in the problem, can't bring data from firebase to show in the UICollectionView.
I can't run collectionView.reloadData() because the UICollectionView is different in class, how should I fix it?
func showImageRewardData(rewardID:String) {
let databaseRef = Database.database().reference().child("reward").child(rewardID).child("rewardImage")
databaseRef.observe(DataEventType.value, with: { (Snapshot) in
if Snapshot.childrenCount>0{
self.rewardDataArr.removeAll()
for rewardImage in Snapshot.children.allObjects as! [DataSnapshot]{
let rewardObject = rewardImage.value as? [String: AnyObject]
if(rewardObject?["imageURL"] != nil){
let imageUrl = rewardObject?["imageURL"]
let Data = rewardDetailClass(rewardImage: imageUrl as? String)
self.rewardDataArr.insert(Data, at: 0)
}
YOURVIEWCONTROLLER.SWIFT
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let CellIdentifier: String = "Cell_NotesList"
var cell: Cell_NotesList? = (tableView.dequeueReusableCell(withIdentifier: CellIdentifier) as? Cell_NotesList)
if cell == nil {
let topLevelObjects: [Any] = Bundle.main.loadNibNamed("Cell_NotesList", owner: nil, options: nil)!
cell = (topLevelObjects[0] as? Cell_NotesList)
cell?.selectionStyle = .none
}
cell?.reloadCollectionView(arr: arrofofthumbImages)
return cell!
}
YourCell.SWIFT
class Cell_NotesList: UITableViewCell {
var imagesArr = NSMutableArray()
override func awakeFromNib() {
collectionView.register(UINib.init(nibName: "cell_ImageCollection", bundle: nil), forCellWithReuseIdentifier: "cell_ImageCollection")
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
extension Cell_NotesList : UICollectionViewDataSource {
func reloadCollectionView(arr:NSMutableArray) {
imagesArr = arr
collectionView.reloadData()
self.layoutIfNeeded()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return imagesArr.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell : cell_ImageCollection? = collectionView.dequeueReusableCell(withReuseIdentifier: "cell_ImageCollection", for: indexPath) as? cell_ImageCollection
//YOUR CODE HERE
return cell!
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
}
}
extension Cell_NotesList : UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 120.0, height: 120.0)
}
}
extension UICollectionViewCell {
var indexPath: IndexPath? {
return (superview as? UICollectionView)?.indexPath(for: self)
}
}
In class that extends UICollectionView, put one setter method like
func setData(data: String){
// Update your cell view here like
Label.text = data
}

In iOS Swift integrate Different array for CollectionView Inside TableView in Swift 4

How to set CollectionView data to Collection tag.collection tag count is not fixed .How to integarte cellForItemAt and numberOfItemsInSection in CollectionView .So I have a collectionView inside of a tableView. I would like to use the values from my array to populate each labels text inside each collectionViewCell. If I print the code below in collectionView cellForItemAt.
class testViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
#IBOutlet weak var providerCategoryTableView: UITableView!
let collectionReuseIdentifier = "selectServiceProviderCollectioncell" // Collection cell identifier in the storyboard
let tableReuseIdentifier = "selectServiceProviderTableViewCell"
var providerCategoryTableViewDictionary = [NSMutableDictionary]()
var providerCategoryCollectionViewDictionary = [String:Any]()
var providerCategoryDictionary = [[String:Any]]()
var ServiceResponse:[[String:Any]] = {[id:1,provider_name:”Telephone”,providers:[{category_name:”Test1”,id:”1”}, {category_name:”Test2”,id:”2”}]], [id:2,provider_name:”MobileNumber”,providers:[{category_name:”Test3”,id:”1”}, {category_name:”Test2”,id:”2”}, {category_name:”Test4”,id:”4”}, {category_name:”Test5”,id:”5”}]]}
var setIndexTag:Int = 0
var cellForItemIndexTag:Int = 0
var exapandTableViewArray = [Int]()
override func viewDidLoad() {
super.viewDidLoad()
initControls()
}
// Expand function
func isExpandable(tableViewHeight:Int) -> Bool {
for item in exapandTableViewArray {
if(tableViewHeight == item){
return true
}
}
return false
}
// MARK: - Private
func initControls(){
providerCategoryTableView.tableFooterView = UIView()
callSelectServiceProvidersAPI()
addServiceProviderLabel.attributedText = GlobalFunctions().addNormalAndBoldText(normalText: NSLocalizedString("RecipientSelectServiceProvidersViewController.addServiceProviderNormalLabel", comment: ""), boldText: NSLocalizedString("RecipientSelectServiceProvidersViewController.addServiceProviderBoldLabel", comment: ""), fontSize : 16.0)
DontSeeYourServiceUILabel.attributedText = GlobalFunctions().addNormalAndBoldText(normalText: NSLocalizedString("RecipientSelectServiceProvidersViewController.DontSeeYourServiceUINormalLabel", comment: ""), boldText: NSLocalizedString("RecipientSelectServiceProvidersViewController.DontSeeYourServiceUIBoldLabel", comment: ""),fontSize : 16.0)
suggestAServiceUIView.layer.borderColor = UIColor( red: CGFloat(115/255.0), green: CGFloat(204/255.0), blue: CGFloat(215/255.0), alpha: CGFloat(1.0) ).cgColor
}
// MARK: - UITableView
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return ServiceResponse.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: tableReuseIdentifier, for: indexPath) as! RecipientSelectServiceProviderTableViewCell
let providerCategoryObject = selectServiceProviderResponse[indexPath.row]
cell.categoryNameLabel.text = (providerCategoryObject["name"] as? String)!
cell.categoryCollectionView.delegate = self
cell.categoryCollectionView.dataSource = self
cell.categoryCollectionView.tag = indexPath.row
cell.categoryCollectionView.reloadData()
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if(isExpandable(tableViewHeight:indexPath.row)){
return 60
}else{
return 120
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedCell = tableView.cellForRow(at: indexPath) as! RecipientSelectServiceProviderTableViewCell
let UpBlueImage = UIImage(named: "up_blue_arrow")
let UpBlueImageData = UIImagePNGRepresentation(UpBlueImage!)
let SelectedImageData = UIImagePNGRepresentation((selectedCell.UpDownImageView.image)!)
if (SelectedImageData == UpBlueImageData){
exapandTableViewArray.append(indexPath.row)
selectedCell.UpDownImageView.image = UIImage(named:"down_blue_arrow")
self.CategoryTableView.beginUpdates()
self.CategoryTableView.endUpdates()
}else{
if let index = exapandTableViewArray.index(of:indexPath.row) {
exapandTableViewArray.remove(at: index)
}
selectedCell.UpDownImageView.image = UIImage(named:"up_blue_arrow")
self.CategoryTableView.beginUpdates()
self.CategoryTableView.endUpdates()
}
}
// MARK: - UICollectionView
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
//return collectioncategories.count
/* if collectionView.tag == 0{
return collectioncategories.count
}else if collectionView.tag == 1{
return collectionSecondcategories.count
}*/
for obj in ServiceResponse {
if collectionView.tag == setIndexTag {
let providers:[[String: Any]] = obj["providers"] as! [[String : Any]]
return providers.count
}
setIndexTag = setIndexTag + 1
}
return 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: collectionReuseIdentifier, for: indexPath) as! RecipientSelectServiceProviderCollectionViewCell
//cell.categoryUILabel.text = collectioncategories[indexPath.row]
/*if collectionView.tag == 0{
cell.categoryUILabel.text = collectioncategories[indexPath.row]
}else if collectionView.tag == 1{
cell.categoryUILabel.text = collectionSecondcategories[indexPath.row]
}*/
for obj in ServiceResponse {
if collectionView.tag == cellForItemIndexTag {
let providers:[[String: Any]] = obj["providers"] as! [[String : Any]]
let data = providers[indexPath.row]
print("providers",providers[indexPath.row])
print("data",data)
for provider in providers {
print("cellForItemAt provider.name",provider["name"] as! String)
cell.categoryUILabel.text! = (provider["name"] as? String)!
print("cell.categoryUILabel.text",cell.categoryUILabel.text!)
}
}
cellForItemIndexTag = cellForItemIndexTag + 1
}
return cell
}
/* func collectionView(_ collectionView: UICollectionView,layout collectionViewLayout: UICollectionViewLayout,sizeForItemAt indexPath: IndexPath) -> CGSize {
let nbCol = 3
let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout
let totalSpace = flowLayout.sectionInset.left + flowLayout.sectionInset.right + (flowLayout.minimumInteritemSpacing * CGFloat(nbCol - 1))
let size = Int((collectionView.bounds.width - totalSpace) / CGFloat(nbCol))
return CGSize(width: size, height: size)
}*/
I want
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
//return collectioncategories.count
if collectionView.tag == 0{
return collectioncategories.count
}else if collectionView.tag == 1{
return collectionSecondcategories.count
}
}
But 0,1....n collectionView.tag not fixed and inside array count also different.Please Its Urgent.Thanks
i have done a similar application where what we did is create one parent array
ie
var tableViewDataArray = [HomeDataHolder] () // which includes the type , sub category in my case myclass contains category name , category id and product array
after this add each category in to this array for me, added dataArry[banners,toppicks,.....]
this is how added class object to arraya
if let categoryes = JSON["categories"] as? NSArray{
for index in 0..<categoryes.count{
self.categoryArray.add(categoryes[index])
}
print(self.categoryArray)
self.session.saveCategory(self.categoryArray)
let catObject = HomeDataHolder(type:"CATEGORY").addCategoryes(categoryArray: self.categoryArray)
self.tableViewDataArray.append(catObject)
}
set tableview datasource as this array
if you need different type design design different cells
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let homeData = tableViewDataArray[indexPath.row] as! HomeDataHolder
if homeData.type == "CATEGORY"{
let cell = tableView.dequeueReusableCell(withIdentifier: "category_name_cell", for: indexPath) as! HomeCategoryTableViewCell
cell.selectionStyle = .none
let dataArray = homeData.dataArray
cell.setProducArray(dataArray!)
cell.delegate = self
return cell
}else if .......
in my HomeCategoryTableViewCell class
func setProducArray(_ data:NSMutableArray){
for index in 0..<data.count{
dataArray.add(data[index])
}
colectionView.reloadData()
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return dataArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "home_categoryes_cellection_cell", for: indexPath) as! HomeCategoriesCollectionViewCell
if let dataDictionary = dataArray[indexPath.row] as? NSDictionary{
utility.setCornerRadius([cell.containerView], cornerRadies: 19)
cell.categoryNameLabel.text = dataDictionary.getStringValue("name")
print(dataDictionary.getStringValue("name"))
}
return cell
}
and my HomeCategoryTableViewCell contains a collection view cell.setProducArray(dataArray!) will change the datasource of the collectionview
In your cellForRow of the TableView access the collectionView with viewWithTag and then give it the indexPath.row in the accessiblityHint property and call reload. Then in the your numberOfSections, numberOfItems or cellForItem methods of collectionView you can access the accessiblityHint property and access your array's index to display the data you want.

How to update tableView data when a CollectionViewCell is clicked ( tableview.reloadData() not working inside CollectionView's didSelectItemAt )

Image 1:
I have a collection view and a table view in the same view controller. I want to update the data of my table view, based on the selected item in the collection view. So every time I click on any item of the collectionView, my tableView data should update.
My code:
public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
for superSkill in skills!{
if superSkill.name == (skills?[indexPath.row].name)! {
childSkills = superSkill.skills!
}
}
DispatchQueue.main.async{
self.childSkillTableView.reloadData()
}
}
Is there any way i can achieve it
First thing is to make sure your childSkillTableView.dataSource = self and your superSkillsCollectionView.delegate = self
The second thing, there's no reason to use DispatchQueue.main.async({})
The third thing, though less important, instead of a for loop, you might use something like:
childSkills = skills?.first(where { superSkill in superSkill.name == (skills?[indexPath.row].name)! }
Though you should use some if let or guard let statements to check for optionals instead of force unwrapping.
extension PerformanceVC: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return skills.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "superSkillCell", for: indexPath) as! SuperSkillCell
cell.superSkillName.text = skills[indexPath.row].name
//loading image async
ImageAsyncLoader.loadImageAsync(url: (skills[indexPath.row].imageURL)!, imgView: cell.superSkillImage)
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
return CGSize(width: skillCollections.frame.height * 0.9, height: skillCollections.frame.height) //use height whatever you wants.
}
public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print((skills[indexPath.row].name)!)
for skill in skills{
if skill.name == (skills[indexPath.row].name)! {
childSkills = skill.skills!
}
}
self.subSkillTableView.reloadData()
}
}
extension PerformanceVC: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let openViewHeight: Int = 55
if (indexPath.row == selectedRowIndex.row && isExpanded == false){
isExpanded = true
return CGFloat(openViewHeight + 36 * (childSkills[indexPath.row].skills?.count)!)
} else if (indexPath.row == selectedRowIndex.row && isExpanded == true){
isExpanded = false
return CGFloat(openViewHeight)
} else {
isExpanded = false
return CGFloat(openViewHeight)
}
}
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return childSkills.count
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print(childSkills[indexPath.row].name)
selectedRowIndex = indexPath
tableView.beginUpdates()
//let cell = tableView.dequeueReusableCell(withIdentifier: "SubSkillTableCell", for: indexPath) as! SubSkillTableCell
let cell = tableView.cellForRow(at: indexPath) as! SubSkillTableCell
for subview in cell.grandSkillStack.subviews {
subview.removeFromSuperview()
}
var grandSkillView: GrandChildSkillItem
grandChildSkills = (childSkills[indexPath.row].skills)!
for grandchildskill in grandChildSkills {
grandSkillView = GrandChildSkillItem(frame: CGRect(x: 0, y: 0, width: 300, height: 30))
grandSkillView.grandChildSkillNameLabel.text = grandchildskill.name
grandSkillView.grandChildSkillProgress.progress = Float(grandchildskill.percentage!)
cell.grandSkillStack.addArrangedSubview(grandSkillView)
}
tableView.endUpdates()
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//tableView.separatorStyle = .none
tableView.showsVerticalScrollIndicator = false
let cell = tableView.dequeueReusableCell(withIdentifier: "SubSkillTableCell", for: indexPath) as! SubSkillTableCell
cell.subSkillName.text = childSkills[indexPath.row].name
cell.subSkillProgress.progress = Float(childSkills[indexPath.row].percentage!)
if let uPoints = childSkills[indexPath.row].userPoints {
if let tPoints = childSkills[indexPath.row].totalPoints {
if let count = childSkills[indexPath.row].skills?.count {
cell.subSkillDetail.text = "\(uPoints)" + "/" + "\(tPoints)" + "XP \u{2022} " + "\(count)" + " subskills"
}
}
}
return cell
}
}

How pass data to an UICollectionView embedded in a TableViewCell (xCode - iOS - Swift 3)

I implemented a CollectionView in a TableViewCell but I need read dynamic data for set cells on CollectionView.
I can read data on extension from class TableViewCell, maybe can help me pass data from ViewController to the class TableViewCell.
class MultipleTableViewCell: UITableViewCell {
#IBOutlet fileprivate weak var collectionView: UICollectionView!
}
extension MultipleTableViewCell : UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 3 // array.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "foodCell", for: indexPath) as! UserCollectionViewCell
let dict = array.object(at: indexPath.row) as! NSDictionary //Like this
cell.name.text = "How do you read data from ViewController"
cell.email.text = "How do you read data from ViewController"
cell.phone.text = dict["phone"] as? String //Like this
cell.image.image = "How do you read data from ViewController"
return cell
}
}
extension MultipleFoodTableViewCell : UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let itemsPerRow:CGFloat = 1
let hardCodedPadding:CGFloat = 20
let itemWidth = (collectionView.bounds.width / itemsPerRow) - hardCodedPadding
let itemHeight = collectionView.bounds.height - (2 * hardCodedPadding)
return CGSize(width: itemWidth, height: itemHeight)
}
}
The simplest way is create one method inside your MultipleTableViewCell with datasource array that you want to fill with CollectionView. Now call this method in cellForRowAt method of TableView.
class MultipleTableViewCell: UITableViewCell {
#IBOutlet fileprivate weak var collectionView: UICollectionView!
var array = [String]() //Change with Your array type
func fillCollectionView(with array: [String]) {
self.array = array
self.collectionView.reloadData()
}
}
Now call this method in cellForRowAt and pass the datasource array for collectionView.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "CellIdentifier") as! MultipleTableViewCell
cell.fillCollectionView(with: ["A","B","C"]) //Pass your array
return cell
}

Resources