UITableView in UICollectionView - ios

I placed a tableView inside a collectionView and added the delegates. The problem is, that I want to control the data in the different tableViews in the collectionView.
Every collectionView holds a label with the name of the current day (e.g.: "Monday"). Below the label is a tableView. In the tableView should be displayed different data, based on the index of the collectionView.
In my example, every tableView has two cells. The tableView in the first item of the collectionView should display: cell1: "1" and cell2: "2", the tableView in the second item should display: cell1: "3" and cell2: "4".
I'm currently using the code below:
import UIKit
class StundenplanCollectionViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UITableViewDataSource, UITableViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
myHours.append(myH0)
myHours.append(myH1)
myHours.append(myH2)
myHours.append(myH3)
myHours.append(myH4)
myHours.append(myH5)
collectionView.delegate = self
collectionView.dataSource = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: Outlets
#IBOutlet weak var collectionView: UICollectionView!
//MARK: Variables
var myDays = ["Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag"]
var myHours: [[String]] = Array() //Array that holds myH1 - myH5
var myH0 = ["1", "2"]
var myH1 = ["3", "4"]
var myH2 = ["5", "6"]
var myH3 = ["7", "8"]
var myH4 = ["9", "10"]
var myH5 = ["Error", "Error"]
var tableLoop = 0
var headerColor: UIColor = UIColor( red: CGFloat(255/255.0), green: CGFloat(140/255.0), blue: CGFloat(60/255.0), alpha: CGFloat(1.0))
//MARK: Table and Collection View
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return myDays.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell: StundenplanCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "stundenplanCollectionCell", for: indexPath) as! StundenplanCollectionViewCell
cell.titleLabel.text = myDays[indexPath.row]
cell.titleLabel.backgroundColor = headerColor
cell.titleLabel.textColor = UIColor.white
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myHours[tableLoop].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: StundenplanTableViewCell = tableView.dequeueReusableCell(withIdentifier: "stundenplanTableCell", for: indexPath) as! StundenplanTableViewCell
cell.titleLabel.text = myHours[/*Here should the indexPath.row of the collectionView item be placed*/][indexPath.row]
return cell
}
}
class StundenplanCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var tableView: UITableView!
}
class StundenplanTableViewCell: UITableViewCell {
#IBOutlet weak var titleLabel: UILabel!
}
Image 1: Here you can see the first tableView in the collectionView (first item of collectionView):
Image 2: Here you can see the second tableView in the collectionView (second Item of collectionView):
Image 3: Storyboard:
Image 4: Structure of the different objects in the view:
Updated code (according to the answer by #missionMan - Thanks by the way!):
import UIKit
class StundenplanCollectionViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.prefersLargeTitles = false
navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.largeTitleDisplayMode = .always
myHours.append(myH0)
myHours.append(myH1)
myHours.append(myH2)
myHours.append(myH3)
myHours.append(myH4)
myHours.append(myH5)
collectionView.delegate = self
collectionView.dataSource = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: Outlets
#IBOutlet weak var collectionView: UICollectionView!
//MARK: Variables
var myDays = ["Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag"]
var myHours: [[String]] = Array() //Array that holds myH1 - myH5
var myH0 = ["1", "2"]
var myH1 = ["3", "4"]
var myH2 = ["5", "6"]
var myH3 = ["7", "8"]
var myH4 = ["9", "10"]
var myH5 = ["Error", "Error"]
var headerColor: UIColor = UIColor( red: CGFloat(255/255.0), green: CGFloat(140/255.0), blue: CGFloat(60/255.0), alpha: CGFloat(1.0))
//MARK: Table and Collection View
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return myDays.count
}
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "stundenplanCollectionViewCell") as? StundenplanCollectionViewCell else { //how can I access the inner tableView? Error: Use of unresolved identifier 'tableView'
return UICollectionViewCell()
}
//set data and reload inner table from outer view controller (StundenplanCollectionViewController according to your code)
cell.dayItems = myHours[indexPath.row]
cell.tableView.reloadData()
//...
return cell
}
class StundenplanCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var tableView: UITableView!
var dayItems: [String] = []
override func awakeFromNib() {
super.awakeFromNib()
self.tableView.delegate = self // <-- set delegates inner table
self.tableView.dataSource = self
}
}
extension StundenplanCollectionViewCell: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dayItems.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: StundenplanTableViewCell = (tableView.dequeueReusableCell(withIdentifier: "stundenplanTableViewCell") as? StundenplanTableViewCell)!
//...
return cell
}
}
class StundenplanTableViewCell: UITableViewCell {
#IBOutlet weak var titleLabel: UILabel!
}

You can add table delegate methods in table cell class
and then you can set data for one day. So each collection cell will have its own table and its own data.
like this:
class StundenplanCollectionViewCell: UICollectionViewCell { //<-- outer cell
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var innerTableView: UITableView! //<-- declare inner table
var dayItems: [String] = []
override func awakeFromNib() {
super.awakeFromNib()
self.innerTableView.delegate = self // <-- set delegates inner table
self.innerTableView.dataSource = self
}
}
extension StundenplanCollectionViewCell: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dayItems.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
...
}
...
set data from outer cell of your collectionView in StundenplanCollectionViewController
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withIdentifier: "stundenplanCollectionViewCell") as? StundenplanCollectionViewCell else { //<-- HERE
return UICollectionViewCell()
}
//set data and reload inner table from outer view controller (StundenplanCollectionViewController according to your code)
cell.dayItems = myH[indexPath.row]
cell.innerTableView.reloadData()
...
return cell
}

Why are you trying to dequeue a UICollectionViewCell from a UITableView?
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath)
...
}

Related

CollectionView inside Tableview loading incorrect data for reused cells

My purpose is to show the header string in each label of collectionview cell.But when I run the top cells which have already loaded are showing correct values in labels while after scrolling the reused cells are showing incorrect values.
Note : The data is fetched from a local file.
My data is as follows:
Trending : 20 items
Mustwatch : 3 items
Newly Added : 8 Items
Popular : 2 items
My code:
ViewController.swift
import UIKit
class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
var videosList:[VideosJSONElement]?
var videosListInstance:VideosDataAccessModel?
#IBOutlet weak var categoriesTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
videosListInstance = VideosDataAccessModel()
videosList = videosListInstance?.videosList
categoriesTableView.dataSource = self
categoriesTableView.delegate = self
categoriesTableView.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return videosList!.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "categoriesCell") as! CategoriesVideoCell
cell.videos = videosList![indexPath.row].nodes
cell.position = indexPath.row
cell.categoryTitle.text = videosList![indexPath.row].title
cell.videosCollectionView.reloadData()
cell.sceneContext = self
return cell
}
}
CategoriesVideoCell.swift
import UIKit
class CategoriesVideoCell: UITableViewCell,UICollectionViewDelegate,UICollectionViewDataSource {
#IBOutlet weak var categoryTitle: UILabel!
var videos:[Node]?
var position:Int!
var sceneContext:UIViewController?
#IBOutlet weak var videosCollectionView: UICollectionView!
override func didMoveToSuperview() {
super.didMoveToSuperview()
videosCollectionView.dataSource = self
videosCollectionView.delegate = self
}
override class func awakeFromNib() {
super.awakeFromNib()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return videos!.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
var cell = collectionView.dequeueReusableCell(withReuseIdentifier: "videoCell", for:indexPath) as! VideoCVCell
cell.node = "\(categoryTitle.text!)"
return cell
}}
The first two cells have correct label text
The reused cells have incorrect data in the label

swift - Dynamic List of items inside tableViewCell

What is the best practice to add dynamic list of items in UITableViewCell with showMore/showLess?
UITableView inside UITableViewCell
I used table view inside my UITableViewCell , but I have issue with reload row at indexPath causes jumpy scrolling.
TableViewController Code :
class ViewController: UIViewController , UITableViewDelegate , UITableViewDataSource , delegatCell {
#IBOutlet weak var tableView: UITableView!
var elementsArray: [data] = []
override func viewDidLoad() {
super.viewDidLoad()
for i in 1...20 {
elementsArray.append(data.init(title: "title\(i)", date: "8:00 PM", isShowMoreClicked: false, elements: ["ToDo\(i)","Aqraa\(i)","ToDo\(i)","ToDo\(i)" , "Mobile Team\(i)" , "Testing Data\(i)"]))
// Do any additional setup after loading the view, typically from a nib.
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return elementsArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let obj = elementsArray[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! expandedTableViewCell
cell.initializeCell()
print(obj.elements)
cell.data = obj.elements
cell.delegate = self
cell.dateLabel.text = obj.date
cell.titleLabel.text = obj.title
cell.showMore.titleLabel?.font = reqularDynamicFont()
cell.showMore.titleLabel?.adjustsFontSizeToFitWidth = true
cell.showMore.tag = indexPath.row
cell.isShowMoreClicked = obj.isShowMoreClicked
cell.tableView.reloadData()
self.view.layoutIfNeeded()
return cell
}
func reqularDynamicFont()-> UIFont{
let font = UIFont.systemFont(ofSize: 15, weight: .regular)
let fontMetrics = UIFontMetrics(forTextStyle: .caption1)
return fontMetrics.scaledFont(for: font)
}
func reloadTableView(indexpath: IndexPath , isShowMoreClicked: Bool) {
elementsArray[indexpath.row].isShowMoreClicked = isShowMoreClicked
tableView.reloadRows(at: [indexpath], with: .automatic)
}
}
ExpandedTableViewCell with inner table view Code :
import UIKit
protocol delegatCell {
func reloadTableView(indexpath: IndexPath , isShowMoreClicked: Bool)
}
class expandedTableViewCell: UITableViewCell , UITableViewDelegate , UITableViewDataSource{
#IBOutlet weak var dateLabel: UILabel!
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var showMore: UIButton!
var data : [String] = []
var initalNum = 2
var isShowMoreClicked: Bool = false
var delegate:delegatCell?
func initializeCell(){
data.removeAll()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if isShowMoreClicked{
return data.count
}else{
return initalNum
}
}
#IBAction func reloadData(_ sender: UIButton) {
delegate?.reloadTableView(indexpath: IndexPath(row: sender.tag, section: 0), isShowMoreClicked: !isShowMoreClicked)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
print(data)
let cell = tableView.dequeueReusableCell(withIdentifier: "simpleTableViewCell", for: indexPath) as! simpleTableViewCell
cell.descLabel.text = data[indexPath.row]
return cell
}
}
I used auto layout to support dynamic height.

Display different arrays in collectionView after click on different rows in tableView

In my viewController i have tableView and collectionView.
And i try to display different arrays in collectionView when i click on different rows in tableView.
So when i click on firstRow in tableView, i want to display firstArray in collectionView, when i click on secondRow in tableView, i want to display secondArray in collectionView and when i click on thirdRow in tableView, i want to display thirdArray in collectionView.
How can i do this?
My test code:
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var collectionView: UICollectionView!
#IBOutlet weak var tableView: UITableView!
var tableArray: [String] = ["1", "2", "3"]
var secondArray: [String] = ["One", "Two"]
var thirdArray: [String] = ["Three", "Four"]
var fourthArray: [String] = ["Five", "Six"]
// TABLEVIEW
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath) as! TableCell
cell.tableLabel.text = tableArray[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print(indexPath)
}
// COLLECTIONVIEW
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return secondArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath) as! CollectionCell
cell.collectionLabel.text = secondArray[indexPath.item]
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print(indexPath)
}
}
class TableCell: UITableViewCell {
#IBOutlet weak var tableLabel: UILabel!
}
class CollectionCell: UICollectionViewCell {
#IBOutlet weak var collectionLabel: UILabel!
}
I understand what need to use condition if, but how to use correct it?
You may add your arrays inside a dictionary (collectionData) using the index as key, in this way their lookup is totally dynamic and you don't need any if then else, so your code might be:
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var collectionView: UICollectionView!
#IBOutlet weak var tableView: UITableView!
var tableArray: [String] = ["1", "2", "3"]
// you may want to feed the dictionary directly with the arrays (feel free to remove them)
var collectionData: [Int: [String]] = [:]
var secondArray: [String] = ["One", "Two"]
var thirdArray: [String] = ["Three", "Four"]
var fourthArray: [String] = ["Five", "Six"]
override func viewDidLoad() {
super.viewDidLoad()
self.collectionData[0] = secondArray
self.collectionData[1] = thirdArray
self.collectionData[2] = fourthArray
}
func getCurrentArray() -> [String]? {
let currentRow = self.tableView.indexPathForSelectedRow?.row ?? 0
let array = self.collectionData[currentRow]
return array
}
// TABLEVIEW
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath) as! TableCell
cell.tableLabel.text = tableArray[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.collectionView.reloadData()
}
// COLLECTIONVIEW
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.getCurrentArray()?.count ?? 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath) as! CollectionCell
cell.collectionLabel.text = self.getCurrentArray()?[indexPath.item]
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print(indexPath)
}
}
class TableCell: UITableViewCell {
#IBOutlet weak var tableLabel: UILabel!
}
class CollectionCell: UICollectionViewCell {
#IBOutlet weak var collectionLabel: UILabel!
}
You can create a dictionary and use it. And with the help of key you can easily fetch the different data from different table view cell.

Adding a collection view inside a table view cell swift 3

I am trying to display table view and once you select a row it shall expand to show a collection view grid of the products within that category. I've managed to get the table view cell expanding and displaying an image, by modifying the height constraint of the image (not the xib method, i tried, no success), following the tutorial below however I cannot seem to get it working if i insert a collection view.
http://codepany.com/blog/swift-3-expandable-table-view-cells/
This is what I am trying to achieve:
My code:
Custom Table view Cell Class
class ExpandableCell: UITableViewCell {
#IBOutlet weak var view: UIView!
#IBOutlet weak var label: UILabel!
#IBOutlet weak var img: UIImageView!
#IBOutlet weak var imgHeightConstraint: NSLayoutConstraint!
#IBOutlet weak var viewHeight: NSLayoutConstraint!
var isExpanded:Bool = false
{
didSet
{
if !isExpanded {
self.imgHeightConstraint.constant = 0.0
} else {
self.imgHeightConstraint.constant = 128.0
}
}
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
View controller
class NewMenuVC: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
// #IBOutlet weak var tableViewCell: UITableViewCell!
// #IBOutlet weak var collectionView: UICollectionView!
// #IBOutlet weak var collectionViewCell: UICollectionViewCell!
let imgs = ["0", "1", "2", "0", "1", "2", "0", "1", "2", "0", "1", "2", "0", "1", "2", "0", "1", "2", "0", "1", "2"]
let categories = ["Hamburgers", "Saver Menu", "Sides", "Desserts", "Drinks", "Offers", "Specials", "Wraps", "Chicken", "Meals"]
var expandedRows = Set<Int>()
//#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.rowHeight = UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:ExpandableCell = tableView.dequeueReusableCell(withIdentifier: "ExpandableCell") as! ExpandableCell
cell.img.image = UIImage(named: imgs[indexPath.row])
cell.isExpanded = self.expandedRows.contains(indexPath.row)
cell.label.text = categories[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 144.0
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print(indexPath.row)
guard let cell = tableView.cellForRow(at: indexPath) as? ExpandableCell
else { return }
switch cell.isExpanded
{
case true:
self.expandedRows.remove(indexPath.row)
case false:
self.expandedRows.insert(indexPath.row)
}
cell.isExpanded = !cell.isExpanded
self.tableView.beginUpdates()
self.tableView.endUpdates()
}
Existing Approach:
I would suggest try using a section header(UITableViewHeaderFooterView). Once you tap on the section header you can set the number of rows to 1.
Here you have to make sure the rowHeight = height of number of items in collection.
This would include too much of work.
Simplify the Approach.
Use the collection view directly , with section header and layout configured for veritical Scroll.
CollectionViewCell.swift
import UIKit
class FriendCVCell: UICollectionViewCell {
#IBOutlet weak var FriendNameLabel: UILabel!
#IBOutlet weak var FriendMobileNOLabel: UILabel!
}
tableCell.swift
import UIKit
class MyPlanTVCell: UITableViewCell {
#IBOutlet weak var collectionView: UICollectionView!
#IBOutlet weak var PlanNameLabel: UILabel!
#IBOutlet weak var MallNameLabel: UILabel!
#IBOutlet weak var PlanDateLabel: UILabel!
var FriendNameArray: NSArray = []
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
collectionView.delegate = self as! UICollectionViewDelegate
collectionView.dataSource = self as! UICollectionViewDataSource
FriendNameArray = ["Sunny", "Mike", "Tom", "Henry", "Jenny", "Neena", "Julia" ]
}
}
extension MyPlanTVCell
: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return FriendNameArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
//
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! FriendCVCell
//What is this CustomCollectionCell? Create a CustomCell with SubClass of UICollectionViewCell
//Load images w.r.t IndexPath
cell.collectionImageView.image = UIImage(named:"default"[indexPath.row])
cell.FriendNameLabel.text = FriendNameArray[indexPath.row] as! String
cell.backgroundColor = UIColor.green
//gameNames[indexPath.row]
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let clickedIndex =
imageNames[indexPath.row]
print(clickedIndex)
}
}

UITableView dataSource from Class object within a UICollectionViewCell

I would like to see each allItems for each object in inventory to be displayed in each row. As it is now, where I have written indexPathOfCollectionView, there's a 0 to see that it is actually working, but I don't know which variable should I write to be able to see each allItems from the inventory.
var inventory = [Item]()
class Item {
var name: String!
var allItems: [String]!
init(name: String, allItems: [String]) {
self.name = name
self.allItems = allItems
}
}
Collection Cell:
class ItemCollectionViewCell: UICollectionViewCell, UITableViewDelegate, UITableViewDataSource {
var inventory = [Item]()
#IBOutlet weak var testTableView: UITableView!
#IBOutlet weak var nameLabel: UILabel!
func configureCell(_ inventory: Item) {
nameLabel.text = inventory[indexPath.row]
testTableView.dataSource = self
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return inventory[indexPathOfCollectionView*].allItems.count
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell: UITableViewCell? = tableView.dequeueReusableCell(withIdentifier: "ItemsCell")
if(cell == nil){
cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "ItemsCell")
}
cell.textLabel?.text = inventory[indexPathOfCollection*].allItems[indexPath.row]
return cell
}
}
This is in the viewController
class VC: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return inventory.count
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionCellItem", for: indexPath) as! ItemCollectionViewCell
let it: Item!
it = inventory[indexPath.row]
cell.configureCell(it)
return cell
}
}
Here is a screenshot of what I've got
From what I can tell, from your class Item remove the Inventory array as it is not needed inside your model. It should be present with the UIViewController. Making the following changes ought to make your code run as required!
Change your UIViewController to-
class VC: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
var inventory = [Item]()
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return inventory.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionCellItem", for: indexPath) as! ItemCollectionViewCell
//Just pass the model inside of the array!
cell.itemsList = inventory[indexPath.item]
cell.configureCell()
return cell
}
}
And inside your UICollectionViewCell:
class ItemCollectionViewCell: UICollectionViewCell, UITableViewDelegate, UITableViewDataSource {
var itemsList : Item!
#IBOutlet weak var testTableView: UITableView!
#IBOutlet weak var nameLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
testTableView.dataSource = self
}
func configureCell() {
testTableView.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return itemsList.allItems.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell: UITableViewCell? = tableView.dequeueReusableCell(withIdentifier: "ItemsCell")
if(cell == nil){
cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "ItemsCell")
}
//get array of strings from inside that particular model!
cell.textLabel?.text = itemsList.allItems[indexPath.row]
return cell
}
}

Resources