Within my CharacterSelectionVC
I have a TableView that is nested in a CollectionView. Each CollectionViewCell represents a part (arms, eyes, pupils, etc.) of my character. Each tableViewCell represents an alternate image for the character part. To display the part’s name, I attached a label to the tableViewCell.
After, selecting a tableView’s cell, how can I pass its label data to my CharacterSelectionVC? I tried creating an instance of the view controller in the table view and passing the label input into the instance’s property but when i print(mouthSelectionCharacterModel)
from CharacterSelectionVC , the array comes back empty. Apologies upfront, if i didn’t correctly follow any coding best practices.
Visual Representation of TableView nested in CollectionView
CollectionViewCell & TableView:
class CharacterInventoryCVCellFinal: UICollectionViewCell, UITableViewDataSource, UITableViewDelegate{
var dataArray2: [String]?
var mouthSelectionFinal: [String] = []
let characterSelectionVC = CharacterSelectionViewController()
@IBOutlet var flexAnimationCustomElements: UILabel!
@IBOutlet var tableView: UITableView!
struct PropertyKeys {
static let tableViewCellID = "tbCell"
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataArray2?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: PropertyKeys.tableViewCellID, for: indexPath)
cell.textLabel!.text = dataArray2?[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let optionChoice = indexPath.row
print(optionChoice)
var str8 = dataArray2?[indexPath.item]
mouthSelectionFinal.append(str8!)
characterSelectionVC.mouthSelectionCharacterModel = mouthSelectionFinal
print(mouthSelectionFinal)
}
}
ViewController & CollectionView:
class CharacterSelectionViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
//MARK: Container for collectionView cell's labels
var elementsForSelection: [String] = ["mouth", "head", "hair", "pupils", "eyes", "eyelids", "eyeBrows", "ears", "neck", "torso", "shoulders", "arms", "hands", "nose"]
//MARK: Container for user selected tableView cell's label
var mouthSelectionCharacterModel: [String] = []
@IBOutlet var characterElementSelectionCollection: UICollectionView!
@IBAction func touchSelectCharacterBt(_ sender: Any) {
applyCharacter()
}
func applyCharacter() {
print(mouthSelectionCharacterModel)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return rawData4.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cellA = collectionView.dequeueReusableCell(withReuseIdentifier: PropertyKeys.collectionViewCellID, for: indexPath) as! CharacterInventoryCVCellFinal
let dataArray = rawData4[indexPath.row]
cellA.updateCellWith2(row: dataArray)
cellA.flexAnimationCustomElements.text = self.elementsForSelection[indexPath.item]
return cellA
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
elementChoice = indexPath.item
print(elementChoice)
}
override func viewDidLoad() {
super.viewDidLoad()
characterElementSelectionCollection.delegate = self
characterElementSelectionCollection.dataSource = self
self.view.addSubview(characterElementSelectionCollection)
let dict = CloneAnimation_20200907.finalize(imageFileNames: characterSVCImageFileNames)
mouthSelection = dict["mouthAngry"]!
headSelection = dict["head1"]!
hairSelection = dict["hair"]!
pupilsSelection = dict["pupilsLeft"]!
eyesSelection = dict["eyeLeft"]!
eyeLidsSelection = dict["eyeLidLeft"]!
eyeBrowsSelection = dict["eyeBrowRight"]!
earsSelection = dict["earRight"]!
neckSelection = dict ["neck"]!
torsoSelection = dict["torso"]!
shouldersSelection = dict["shoulderLeft"]!
armsSelection = dict["armLowerLeft"]!
handsSelection = dict["handLeft"]!
noseSelection = dict["nose"]!
rawData4 = [mouthSelection, headSelection, hairSelection, pupilsSelection, eyesSelection, eyeLidsSelection, eyeBrowsSelection, earsSelection, neckSelection, torsoSelection, shouldersSelection, armsSelection, handsSelection, noseSelection]
}
}
Extensions
//MARK: To help pass along data for tableView
extension CharacterInventoryCVCellFinal{
func updateCellWith2(row: [String]) {
self.dataArray2 = row
self.tableView.reloadData()
}
}
2
Answers
Your ViewController is managing the collection view.
Your CollectionViewCell is managing the table view.
So, when you get
didSelectRowAt
in your CollectionViewCell, it needs to tell the Controller what was selected, and let the controller update the data.Here’s a quick example…
Simple Struct for the data
Single label table view cell
Collection View cell with embedded table view
Example view controller
When you run that it will look like this – and when you select a "part" the label at the bottom will be updated with the selection. The data
.selectedPart
property will also be updated, so each table view will maintain its previously selected row:In your cell classes you can have a delegate, and you can send your pass your data using that delegate methods.
Hope it helps.