loading a UITableViewController from a selected indexpath in a UICollectionViewController - ios

Im trying to get the VC that corresponds with the cell of the table view to load when tapped. I am trying to set the indexPath as the selectedIndexPath and set up the segue in the collection view, then use that in the tableView but it is throwing an error. Here is the code.
import UIKit
private let reuseIdentifier = "profileCell"
class CompanyCollectionViewController: UICollectionViewController {
//MARK: - View Did Load
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .Plain, target: nil, action: nil)
}
// MARK: UICollectionViewDataSource
override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return stuff.company.count
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! ProfileCollectionViewCell
cell.profileImageView.image = UIImage(named: stuff.company[indexPath.row]["image"]!)
return cell
}
//MARK: - Prepare For Segue
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "profileSegue" {
let profileVC = segue.destinationViewController as!
MyProfileTableViewController
let cell = sender as! UICollectionViewCell
let indexPath = collectionView?.indexPathForCell(cell)
profileVC.selectedIndexPath = indexPath
}
}
}
and then
import UIKit
class MyProfileTableViewController: UITableViewController {
//MARK: - View Did Load
override func viewDidLoad() {
super.viewDidLoad()
}
//MARK: - Table View Data Source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if let indexPath = selectedIndexPath {
let row = stuff.company[indexPath.row]
let cell = tableView.dequeueReusableCellWithIdentifier("myProfileCell", forIndexPath: indexPath) as! MyProfileTableViewCell
cell.heroImageView.image = UIImage(named: row["image"]!)
title = row["name"]
cell.nameLabel.text = row["name"]
cell.statusLabel.text = row["description"]
return cell
} else {
let cell = tableView.dequeueReusableCellWithIdentifier("myProfileCell", forIndexPath: indexPath) as! MyProfileTableViewCell
cell.heroImageView.image = UIImage(named: stuff.profile["profile image"]!)
title = stuff.profile["name"]
cell.nameLabel.text = stuff.profile["name"]
cell.statusLabel.text = stuff.profile["status"]
return cell
}
}
//MARK: - Variables
var selectedIndexPath: NSIndexPath?
}

Ah I see, you are not checking if your collectionView?.indexPathForCell is returning a valid result.
if let cell = sender as? UICollectionViewCell {
// Cell is valid
if let indexPath = collectionView?.indexPathForCell(cell) {
// indexPath is valid
} else {
// indexPath is invalid
}
} else {
// cell is invalid
}
I suspect your indexPath from your table and your indexPath from your selection view are being mixed up, the code posted above should help you debug that.
Beyond that, I believe you can accomplish your intended result by:
1) Saving your selectedIndexPath in the didSelectCellAtIndexPath: method
2) Reading the selectedIndexPath in prepareForSegue instead of deriving the indexPath from the segue sender

Related

UITableView Multi Selection's selected checkmark not remains checked

I have two UITableView in my application.
One is for Category and Second is for SubCategory.
On the basis of selected Category SubCategory UITableView, data will change, and SubCategory UITableView have multi-selection functionality, till this my application is working fine.
Now the problem is when I am on category UITableView and click on suppose Category cell it will redirect to the various subCategory, On that screen, I have selected multiple choices and click on back button appear on top, and when I click again on Category tab my selection(Checkmark) is disappearing.
I want my checkmark to be selected as long as I manually set them as unchecked.
How can I implement that thing?
Sample screenshot of my application attached below.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tblSubCategory.cellForRow(at: indexPath)
if cell!.isSelected
{
cell!.isSelected = false
if cell!.accessoryType == UITableViewCell.AccessoryType.none
{
if strCategoryData == "Category" {
cell!.accessoryType = UITableViewCell.AccessoryType.checkmark
let objectForCell = arrSubCategoryData[indexPath.row]
arrSelectedCetegoryIndex.append(objectForCell)
let defaults = UserDefaults.standard
defaults.set(arrSelectedCetegoryIndex, forKey: "categoryKey")
}
else if strCategoryData == "Brand" {
cell!.accessoryType = UITableViewCell.AccessoryType.checkmark
let objectForCell = arrSubCategoryData[indexPath.row]
arrSelectedBrandIndex.append(objectForCell)
}
else if strCategoryData == "Color" {
cell!.accessoryType = UITableViewCell.AccessoryType.checkmark
let objectForCell = arrSubCategoryData[indexPath.row]
arrSelectedColorIndex.append(objectForCell)
}
else if strCategoryData == "Size" {
cell!.accessoryType = UITableViewCell.AccessoryType.checkmark
let objectForCell = arrSubCategoryData[indexPath.row]
arrSelectedSizeIndex.append(objectForCell)
}
}
else
{
if strCategoryData == "Category" {
cell!.accessoryType = UITableViewCell.AccessoryType.none
let selectedIndex = (tblSubCategory.indexPathForSelectedRow?.row)!
let selectedIndexValue = arrSubCategoryData[selectedIndex]
print(selectedIndexValue)
let index = arrSelectedCetegoryIndex.firstIndex(of: selectedIndexValue)!
arrSelectedCetegoryIndex.remove(at: index)
}
else if strCategoryData == "Brand" {
cell!.accessoryType = UITableViewCell.AccessoryType.none
let selectedIndex = (tblSubCategory.indexPathForSelectedRow?.row)!
let selectedIndexValue = arrSubCategoryData[selectedIndex]
print(selectedIndexValue)
let index = arrSelectedBrandIndex.firstIndex(of: selectedIndexValue)!
arrSelectedBrandIndex.remove(at: index)
}
else if strCategoryData == "Color" {
cell!.accessoryType = UITableViewCell.AccessoryType.none
let selectedIndex = (tblSubCategory.indexPathForSelectedRow?.row)!
let selectedIndexValue = arrSubCategoryData[selectedIndex]
print(selectedIndexValue)
let index = arrSelectedColorIndex.firstIndex(of: selectedIndexValue)!
arrSelectedColorIndex.remove(at: index)
}
else if strCategoryData == "Size" {
cell!.accessoryType = UITableViewCell.AccessoryType.none
let selectedIndex = (tblSubCategory.indexPathForSelectedRow?.row)!
let selectedIndexValue = arrSubCategoryData[selectedIndex]
print(selectedIndexValue)
let index = arrSelectedSizeIndex.firstIndex(of: selectedIndexValue)!
arrSelectedSizeIndex.remove(at: index)
}
}
}
}
You are probably performing a segue to go to the sub category view controller, and every time you perform this segue, tableview delegate and datasource methods are called again and cells are initialized all over again.
For you to show your cells checked you are going to need to save the checked values in the Categories view controller and pass them to the SubCategory View Controller and set the checked values in your cellForRowAtIndexpath method.
Here is an example on how to implement that:
class CategoryViewController: UIViewController {
var checkedValues = [[Bool]]()
var indexSelected = -1
override func viewDidLoad() {
super.viewDidLoad()
// your code here
checkedValues.append(contentsOf: repeatElement([], count: yourCategArray.count))
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// your code here
indexSelected = indexPath.row
self.performSegue(withIdentifier: "yourSegueIdentifierHere", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
(segue.destination as! SubCategoryViewController).parentCategoryVC = self
}
}
Now for the other View Controller:
class SubCategoryViewController: UIViewController {
var parentCategoryVC = CategoryViewController()
override func viewDidLoad() {
super.viewDidLoad()
if parentCategoryVC.checkedValues[parentCategoryVC.indexSelected].count == 0 {
parentCategoryVC.checkedValues[parentCategoryVC.indexSelected].append(contentsOf: repeatElement(false, count: yourSubCategArray.count))
}
// your code here
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return yourSubCategArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell...
if parentCategoryVC.checkedValues[parentCategoryVC.indexSelected][indexPath.row] { cell.accessoryType = .checkmark } else { cell.accessoryType = .none }
// your code here
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// your code
parentCategoryVC.checkedValues[parentCategoryVC.indexSelected][indexPath.row] = !parentCategoryVC.checkedValues[parentCategoryVC.indexSelected][indexPath.row]
tableView.reloadRows(at: indexPath, with: UITableViewRowAnimation.none)
}
}
For any additional clarification feel free to ask
You need to create one Int type array and then append value on click if not in array and if already exist so you need to remove from array and set checkmark in cellForRowAt method.
Please See complete code
import UIKit
class testViewController: UIViewController {
var selectedRows: [Int] = []
override func viewDidLoad() {
super.viewDidLoad()
}
}
extension testViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")!
cell.textLabel?.text = "Welcome " + (indexPath.row+1).description
cell.selectionStyle = .none
cell.accessoryType = selectedRows.contains(indexPath.row) ? .checkmark : .none
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 50
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if self.selectedRows.contains(indexPath.row) {
if let index = self.selectedRows.firstIndex(of: indexPath.row) {
self.selectedRows.remove(at: index)
}
} else {
self.selectedRows.append(indexPath.row)
}
tableView.reloadData()
}
}

How can I pass data through segue from a collectionViewCell and button embedded in TableViewCell?

I wish to pass data through segue from a collectionViewCell embedded in a TableViewCell;
Also from a Button embedded in a TableViewCell
Here is the sample code :
Here is the TableViewCell's class :
class PopularCell: UITableViewCell {
#IBOutlet weak var ViewAllButton: UIButton!
#IBOutlet weak var PopularEvents: UILabel!
#IBOutlet weak var EventCollection: UICollectionView! // EMBEDDED COLLECTIONVIEW
var events = [Events]()
override func awakeFromNib() {
super.awakeFromNib()
// EMBEDDED BUTTON
ViewAllButton.setIcon(prefixText: "View All ", prefixTextColor: .blue, icon: .typIcons(.chevronRight), iconColor: .blue, postfixText: " ", forState: .normal, iconSize: 24) // EMBEDDED BUTTON
EventCollection.delegate = self
EventCollection.dataSource = self
}
extension PopularCell: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return events.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = EventCollection.dequeueReusableCell(withReuseIdentifier: "EventCell", for: indexPath) as! EventCell
let event = events[indexPath.row]
print("Event Name:\(event.event_name)")
cell.event = event
return cell
}
}
Here is the ViewController(TableView Delegate & DataSource) class :
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return groupedEventArray.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 245
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "PopularCell", for: indexPath) as! PopularCell
let (category, events) = groupedEventArray[indexPath.row]
cell.ViewAllButton.addTarget(self, action: #selector(VenueViewController.ViewAll(_:)), for: .touchUpInside)
cell.PopularEvents.text = category
cell.events = events
return cell
}
#objc func ViewAll(_ sender:UIButton!) {
self.performSegue(withIdentifier: "ViewEvents", sender: sender)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if(segue.identifier == "ViewEvents") {
let destination = segue.destination as? EventListController
destination?.navigationItem.title = "Event Category"
}
else if(segue.identifier == "ViewEventDetails") {
if let collectionCell: EventCell = sender as? EventCell {
if let _: UICollectionView = collectionCell.superview as? UICollectionView {
let destination = segue.destination as? EventDetailViewController
destination?.navigationItem.title = "Event Details"
}
}
}
}
How do I configure the func prepare so as to pass data through the "ViewEvents" & "ViewEventDetails" segue identifiers accordingly

UICollectionView inside UITableViewCell returning empty always even though shows as selected

I am using a UICollectionView inside UITableViewCell. I am able to select the cells inside the UICollectionView. But when i try to get the UICollectionView or selected cells, the result is always null.I have been stuck on this for a long time. i included my code below for your reference.
class WeekDaysSelCell: UITableViewCell,UICollectionViewDelegate, UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {
var weekdays = ["S", "M", "T", "W", "T", "F", "S"]
var weekdaysSelected = [String]()
#IBOutlet var weeklyDaysColView: UICollectionView!
override func awakeFromNib() {
super.awakeFromNib()
self.weeklyDaysColView.delegate = self
self.weeklyDaysColView.dataSource = self
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 7
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell : WeekDaysCollCell = weeklyDaysColView.dequeueReusableCell(withReuseIdentifier: "weekday", for: indexPath) as! WeekDaysCollCell
cell.weekDayLabel.text = weekdays[indexPath.row]
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell : WeekDaysCollCell = self.weeklyDaysColView.cellForItem(at: indexPath) as! WeekDaysCollCell
if (cell.backgroundColor == UIColor.gray) {
cell.backgroundColor = UIColor.clear
weekdaysSelected.removeAll { $0 == String(indexPath.row)}
//print("Removed from weekdaysSelected:", indexPath.row)
} else {
cell.backgroundColor = UIColor.gray
cell.isSelected = true
//weeklyDaysColView.selectItem(at: indexPath, animated: true, scrollPosition: [])
weekdaysSelected.append(String(indexPath.row))
//print("Added to weekdaysSelected:", indexPath.row)
}
}
}
// Trying to get the collection view from inside a willMove(toParent parent: UIViewController?) method.
override func willMove(toParent parent: UIViewController?) {
super.willMove(toParent: parent)
if parent == nil
{
if let delegate = self.delegate {
print("Inside If condition")
// Code that i use to get the cell
let cell3 = tableView.dequeueReusableCell(withIdentifier: "cell3") as! WeekDaysSelCell
print(cell3.weekdaysSelected)
print(cell3.weeklyDaysColView.indexPathsForSelectedItems)
// Trying to pass selected cells
//delegate.repeatCustomSelection(selectedIdx: String(lastSelection.row),repeatCustomSel: repeatCustomSelection)
}
}
}
You are trying to get a reusable cell in willMove(toParent parent: UIViewController?) , this is not going to return you a expected cell.
You need to get the cell , using a indexPath .
func cellForRow(at indexPath: IndexPath) -> UITableViewCell?
#andyPaul, is right you are generating the new cell in willMove(toParent parent: UIViewController?). Instead of that you have to pass the indexpath pf collection view when ever user selected any cell to your controller from the tableView Cell Class.
Now What is TypeAlias you can read from this link about type alias:- https://www.programiz.com/swift-programming/typealias
Create the typeAlias on above of your tableViewCell Class like this:-
typealias closureBlock = (_ isCapture : AnyObject?) ->()
class tableViewCellClass: UITableViewCell {
var callBack: closureBlock?
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
Just Go to CollectionView didSelectItemAt Method and use this code after your coding
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell : WeekDaysCollCell = self.weeklyDaysColView.cellForItem(at: indexPath) as! WeekDaysCollCell
if (cell.backgroundColor == UIColor.gray) {
cell.backgroundColor = UIColor.clear
weekdaysSelected.removeAll { $0 == String(indexPath.row)}
//print("Removed from weekdaysSelected:", indexPath.row)
} else {
cell.backgroundColor = UIColor.gray
cell.isSelected = true
//weeklyDaysColView.selectItem(at: indexPath, animated: true, scrollPosition: [])
weekdaysSelected.append(String(indexPath.row))
//print("Added to weekdaysSelected:", indexPath.row)
}
guard let callBackClosure = self.callBack else {
return
}
callBackClosure(indexPath as AnyObject)
// You can pass any value here either indexpath or Array.
}
}
Now you have to initialise this closure so that it can check whether in which controller it will return the value when you assign the value from CollectionView didSelectItemAt Method.
Go to your ViewController Class where you have added the tableview and their datasources.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//You have to pass your tableview Cell Instance here and their reuse Identifier
let cell = tableView.dequeueReusableCell(withIdentifier: "tableViewCellClass", for: indexPath) as! tableViewCellClass
cell.callBack = { [weak self] (selectedIndexPath) -> ()in
// You will get the current selected index path of collection view here, Whenever you pass any index path from collectionView did SelectItem Method.
print(selectedIndexPath)
}
return cell
}

Can't get the data on class uitableview Swift 3

I'm having trouble presenting the data. I have copied the code from https://stackoverflow.com/a/39307841/7118403 because i want to test his method on saving the checkmark. But unfortunately I can't present the data on tableView. When i try to print the "myItems" it shows [tableViewCheckmark.Item]. I can't seem to find the solution. PS. I'm a new to programming. Thank you in advance.
class Item {
let name : String
var selected = false
init(name: String) {
self.name = name
}
}
class TableViewController: UITableViewController {
#IBOutlet var uiTableView: UITableView!
var myItems = [Item]()
override func viewDidLoad() {
uiTableView.reloadData()
}
override func viewWillAppear(_ animated: Bool) {
let item = Item(name:"Foo")
myItems.append(item)
print(myItems)
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath as IndexPath)
let item = myItems[indexPath.row]
cell.textLabel!.text = item.name
cell.accessoryType = item.selected ? .checkmark : .none
cell.selectionStyle = .none
cell.tintColor = UIColor.green
return cell
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
saveDefaults()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return myItems.count
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let item = myItems[indexPath.row]
item.selected = true
tableView.reloadRows(at: [indexPath as IndexPath], with: .none)
}
func saveDefaults() {
let selectedCells = myItems.filter { $0.selected }.map { $0.name }
let defaults = UserDefaults.standard
defaults.set(selectedCells, forKey:"selectedCells")
}
func readDefaults()
{
let defaults = UserDefaults.standard
let selectedItems = defaults.stringArray(forKey: "selectedCells")!
for item in myItems {
item.selected = selectedItems.contains(item.name)
}
tableView.reloadData()
}
}
Signature of UITableViewDataSource methods is changed in Swift 3 also you are currently passing array count in numberOfSections(in:) remove it and add below methods.
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myItems.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath as IndexPath)
let item = myItems[indexPath.row]
cell.textLabel!.text = item.name
cell.accessoryType = item.selected ? .checkmark : .none
cell.selectionStyle = .none
cell.tintColor = UIColor.green
return cell
}
override func tableView(tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let item = myItems[indexPath.row]
item.selected = true
tableView.reloadRows(at: [indexPath], with: .none)
}

reloadData is not calling cellForRowAtIndexPath

I know this topic has been raised quite a few times but I can't seem to get through.
This is a simple UITableViewController who's cells are either normal UITableViewCells or custom ones.
This allow users to input text in a textField in a cell and add it directly to the tableView.
When the user is done entering his text he hits return and the new entry gets added to listOfItems. At this point I want my tableView to reload its data to show the last item added.
Doesn't seem to work.
class CreateListTableViewController: UITableViewController {
// MARK: - Model
var listOfItems = [String]()
{
didSet {
tableView.reloadData()
println(listOfItems)
}
}
// MARK: - View LifeCycle
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBarHidden = false
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return listOfItems.count + 1
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.row + 1 == listOfItems.count{
let cell = tableView.dequeueReusableCellWithIdentifier("tableCellSearch", forIndexPath: indexPath) as! ListItemTableViewCell
cell.configure(text: "", placeholder: "Enter an item")
return cell
} else {
let cell = tableView.dequeueReusableCellWithIdentifier("tableCell", forIndexPath: indexPath) as! UITableViewCell
println(indexPath.row)
cell.textLabel?.text = listOfItems[indexPath.row]
return cell
}
}
}
Here's the code for the custom UITableViewCell:
class ListItemTableViewCell: UITableViewCell, UITextFieldDelegate {
#IBOutlet weak var cellTextField: UITextField!
var controllerArray = CreateListTableViewController()
func configure(#text: String?, placeholder: String){
cellTextField.text = text
cellTextField.placeholder = placeholder
cellTextField.accessibilityValue = text
cellTextField.accessibilityLabel = placeholder
}
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
textField.text = ""
return true
}
override func awakeFromNib() {
super.awakeFromNib()
cellTextField.delegate = self
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
controllerArray.listOfItems += [textField.text]
textField.text = ""
return true
}
func textFieldShouldEndEditing(textField: UITextField) -> Bool {
return true
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
Interestingly reloadData calls 'numberOfRows' but not 'cellForRow'.
Your indexes/sizes are off such that your code only works when listOfItems' size is 0. Try this:
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return listOfItems.count + 1
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.row == listOfItems.count {
let cell = tableView.dequeueReusableCellWithIdentifier("tableCellSearch", forIndexPath: indexPath) as! ListItemTableViewCell
cell.configure(text: "", placeholder: "Enter an item")
return cell
} else {
let cell = tableView.dequeueReusableCellWithIdentifier("tableCell", forIndexPath: indexPath) as! UITableViewCell
println(indexPath.row)
cell.textLabel?.text = listOfItems[indexPath.row]
return cell
}
}
Update:
OK, the problem is that in ListItemTableViewCell you are creating a new instance of CreateListTableViewController and assigning it to controllerArray. This means that when you call controllerArray.listOfItems += [textField.text], you are calling it on a separate, second instance of CreateListTableViewController that is not on the screen.
Instead, you should leave controllerArray uninitialized in ListItemTableViewCell and then set it from cellForRowAtIndexPath like this:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.row + 1 == listOfItems.count{
let cell = tableView.dequeueReusableCellWithIdentifier("tableCellSearch", forIndexPath: indexPath) as! ListItemTableViewCell
cell.configure(text: "", placeholder: "Enter an item")
cell.controllerArray = self
return cell
} else {
let cell = tableView.dequeueReusableCellWithIdentifier("tableCell", forIndexPath: indexPath) as! UITableViewCell
println(indexPath.row)
cell.textLabel?.text = listOfItems[indexPath.row]
return cell
}
}
Can you make sure that your internal list is updated correctly and the numberOfRowsInSection functions returns number other than 0 or 1?

Resources