i have a UITableView with multiple selection enabled with checkmarks. When i make selection that are all visible in the view, i don't run into any errors. However, if i scroll down further and place a selected item out of view, i get errors and even though the row stays selected, the checkmark goes away.
import Foundation
import Parse
import UIKit
class customerMenuVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var menuTV: UITableView!
var menuItems: [String] = ["Hello"]
var menuPrices: [Double] = [0.0]
var orderSelection: [String] = []
var priceSelection: [Double] = []
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return menuItems.count
}
func tableView(tableView: UITableView, numberOfColumnsInSection section: Int) -> Int
{
return 1;
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell:UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "mycell")
cell.textLabel!.text = "\(menuItems[indexPath.row])\t $\(menuPrices[indexPath.row])"
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
//tableView.deselectRowAtIndexPath(indexPath, animated: true)
let cell = tableView.cellForRowAtIndexPath(indexPath)
cell!.accessoryType = .Checkmark
orderSelection.append(cell!.textLabel!.text!)
}
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath)
{
let cell = tableView.cellForRowAtIndexPath(indexPath)
cell!.accessoryType = .None
}
override func viewDidLoad() {
super.viewDidLoad()
menuTV.allowsMultipleSelection = true
let resMenu = resUser.sharedInstance
var resName = resMenu.nameStr
var resID = resMenu.idStr
var menuQ = PFQuery(className: "menu")
menuQ.getObjectInBackgroundWithId(resID){
(menus: PFObject?, error: NSError?) -> Void in
if error == nil && menus != nil {
let items: [String] = menus?.objectForKey("menuItems") as! Array
let prices: [Double] = menus?.objectForKey("menuPrices") as! Array
self.menuItems = items
self.menuPrices = prices
self.menuTV.reloadData()
}
}
}
#IBAction func continueButton(sender: AnyObject) {
let selections = menuTV.indexPathsForSelectedRows() as! [NSIndexPath]
var indexCount = selections.count
println(indexCount)
var x = 0
while x < indexCount
{
println(x)
let currentCell = menuTV.cellForRowAtIndexPath(selections[x]) as? UITableViewCell?;
println(x)
println(selections[x].row.description)
orderSelection.append(currentCell!!.textLabel!.text!)
println(orderSelection[x])
x++
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
This is how table views work.
When a cells scrolls off-screen, it gets tossed into the recycle queue and then used again to display data for a different indexPath in your data.
Any time the user makes any changes to the data for a cell you should save it to your data model (usually an array of information, or maybe an array of arrays if you're using a sectioned table view.) Then you should tell the table view to redisplay the changed cell. The cellForRowAtIndexPath method picks up the changed data and shows the changes to the cell. If the cell scrolls off-screen and then scrolls back on-screen, it gets displayed with the correct settings.
This applies to keeping track of which cells are selected as well.
Related
I am trying to make a simple Times Table App (for numbers 1-9) in Swift) using a slider and a Table View. I am managing to make the slider work and an array to be created for each number that is selected with the slider and although the array is shown on the console. I cannot get the numbers to appear on the Table View. Can you please help me and tell me what am I missing?
Here is what I have written so far:
class ViewController: UIViewController, UITableViewDelegate {
#IBOutlet var sliderValue: UISlider!
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 9
}
#IBAction func sliderMoved(sender: UISlider) {
sender.setValue(Float(lroundf(sliderValue.value)), animated: true)
print(sliderValue)
var cellContent = [String]()
for var i = 1; i <= 10; i += 1 {
cellContent.append(String(i * Int(sliderValue.value)))
}
print(cellContent)
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
cell.textLabel?.text = cellContent[indexPath.row]
return cell
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I'm afraid there's quite a lot in the code you've supplied that doesn't make all that much sense. I've mentioned some of it in my comment above but you've also nested what looks like a tableViewDataSource-function into your sliderMoved function. The whole array thing looks rather flakey as well as the proposed cell-count does not actually consider the size of the array. I think you probably want something like this:
class ViewController: UIViewController, UITableViewDataSource {
#IBOutlet var valueSlider: UISlider!
#IBOutlet var tableView: UITableView!
private var cellContent = [String]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
}
#IBAction func sliderMoved(sender: UISlider) {
sender.setValue(Float(lroundf(valueSlider.value)), animated: true)
tableView.reloadData()
}
// TableViewDataSource
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 9
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell") // Must exist with the same identifier in your storyboard
cell.textLabel?.text = valueStringForIndex(indexPath.row)
return cell
}
// Private functions
private func valueStringForIndex(index: Int) -> String {
return "\(index * Int(valueSlider.value))"
}
}
Have you tried creating cellContent array as a instance variable and the following code may work. Check it once.
var cellContent = [String]()
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 9
}
#IBAction func sliderMoved(sender: UISlider) {
sender.setValue(Float(lroundf(sliderValue.value)), animated: true)
print(sliderValue)
for var i = 1; i <= 10; i += 1 {
cellContent.append(String(i * Int(sliderValue.value)))
}
print(cellContent)
self.tableview.reloadData()
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
cell.textLabel?.text = cellContent[indexPath.row]
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Although not directly an answer to your question ->
Depending on how you want the table displayed, a UICollectionView may be a great fit for this application. Very similar to UITableView to implement but with boxes and columns of data, may be simpler to format (and changing the slider could add some fun animation when the collection view updates).
The sample UIViewController below demonstrates using a UICollectionView. In the storyboard, I simply:
Added a UISlider, UICollectionView, and UILabel and created outlets in MultiplicationTableViewController
In the UICollectionView default cell I gave it the reuseIdentifier "numberCell", and added a label (to hold the product)
Made the MultiplicationTableViewController the dataSource and delegate for the UICollectionView
CODE:
import UIKit
class MultiplicationTableViewController: UIViewController {
#IBOutlet var timesTableCollectionView: UICollectionView!
#IBOutlet weak var numberSlider: UISlider!
#IBOutlet weak var label: UILabel!
var products = [Int]() //array to hold the computed value for each cell in the collectionView
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.viewRotated), name: UIDeviceOrientationDidChangeNotification, object: nil) //register for rotation notifications
products = createTableOfValues() //populate products with initial values
label.text = "\(Int(numberSlider.value)) x \(Int(numberSlider.value))"
}
#IBAction func sliderUpdated(sender: UISlider) {
sender.value = Float(Int(sender.value)) //make the slider stop only on whole numbers
label.text = "\(Int(sender.value)) x \(Int(sender.value))"
products = createTableOfValues() //create the new table values
timesTableCollectionView.reloadData() //tell the collectionView to read the new data and refresh itself
}
func createTableOfValues() -> [Int] {
var prod = [Int]() //temp array to hold the generated products
for row in 0...Int(numberSlider.value) { //iterate from row 0 (header) to
var columns = [Int]() //temp array to build column products
for column in 0...Int(numberSlider.value) {//iterate through each column, including column 0 (header)
if column == 0 {
columns.append(row)
} else if row == 0 {
columns.append(column)
} else {
columns.append(column * row)
}
}
prod.appendContentsOf(columns) //add the current row of products to the temp array
}
return prod
}
func viewRotated() {
timesTableCollectionView.reloadData() //called to force collectionView to recalc (basically to get new cell sizes
}
}
extension MultiplicationTableViewController: UICollectionViewDataSource {
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1 //required for UICollectionViewDataSource
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return Int(numberSlider.value + 1) * Int(numberSlider.value + 1) //tells the UICollectionView how many cells to draw (the number on the slider, plus header rows)
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("numberCell", forIndexPath: indexPath) //get an existing cell if it exists
if cell.frame.origin.y == 0.0 || cell.frame.origin.x == 0.0 { //if the cell is at the top or left of the collectionView
cell.backgroundColor = UIColor.yellowColor()
} else {
cell.backgroundColor = UIColor.clearColor() //If not, reset the color (required because cells are reused
}
cell.layer.borderColor = UIColor.blackColor().CGColor
cell.layer.borderWidth = 1.0
let numberItem = cell.viewWithTag(101) as? UILabel //get a reference to the label in the current cell
numberItem?.text = String(products[indexPath.row]) //get the value generated earlier for this particular cell
return cell
}
}
extension MultiplicationTableViewController: UICollectionViewDelegateFlowLayout {
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
let columns = CGFloat(numberSlider.value + 1) //get the number of columns - slider value + 1 for header
let width = timesTableCollectionView.bounds.width / columns //divide the width of the collectionView by the number of columns
return CGSizeMake(width, width) //use width value to make the cell a square
}
}
Screenshot:
I have a 2D Array which I want to populate in UITableView Custom Cell in a specific pattern.
//Retrieved from Parse backend
var myArray = [["Name1", "Age1"],["Name2", "Age2"],["Name3", "Age3"]]
//What I need is:
nameArray = ["Name1", "Name2", "Name3"]
ageArray = ["Age1", "Age2", "Age3]
So that I can use indexPath to fill the Name data in the custom UITableView cell For Ex: nameArray[indexPath.row]
I tried using the for in loop,
var nameArray = NSMutableArray()
var ageArray = NSMutableArray()
//Inside CellForRowAtIndexPath
for data in myArray {
self.nameArray.addObject(data[0])
self.ageArray.addObject(data[1])
}
cell.nameLabel.text = "\(nameArray[indexPath.row])"
cell.ageLabel.text = "\(ageArray[indexPath.row])"
But I am getting repetitive name and age label filled with Name1 and Age1 in both the cell. Does anyone know whats wrong in this?
Is there a better way to reload this data as needed?
// UPDATED FULL WORKING CODE Thanks to #l00phole who helped me solve the problem
class NewViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var tableView: UITableView!
var data = [[String]]()
var cost = Double()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
uploadData()
}
func uploadData() {
let query = PFQuery(className:"Booking")
query.getObjectInBackgroundWithId("X0aRnKMAM2") {
(orders: PFObject?, error: NSError?) -> Void in
if error == nil && orders != nil {
self.data = (orders?.objectForKey("orderDetails"))! as! [[String]]
//[["Vicky","21"],["Luke", "18"],["7253.58"]]
//*****Removing the last element as it is not needed in the tableView data
let count = self.data.count - 1
let c = self.data.removeAtIndex(count)
cost = Double(c[0])!
//******
} else {
print(error)
}
self.reloadTableData()
}
}
func reloadTableData()
{
dispatch_async(dispatch_get_main_queue(), {
self.tableView.reloadData()
return
})
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return data.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:NewTableViewCell = self.tableView!.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! NewTableViewCell
// Configure the cell...
cell.nameLabel.text = "\(data[indexPath.row][0])"
cell.ageLabel.text = "\(data[indexPath.row][1])"
return cell
}
You are adding to the nameArray and ageArray every time cellForRowAtIndexPath is called and you are not clearing them first. This seems inefficient and you should only populate those arrays when the input data changes, not when generating the cells.
I don't even think you need those arrays, as you could just do:
cell.nameLabel.text = "\(data[indexPath.row][0])"
cell.ageLabel.text = "\(data[indexPath.row][1])"
You don't have to create separate array for name and age, you can use the existing myArray as below
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:NewTableViewCell = self.tableView!.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! NewTableViewCell
// Configure the cell...
let dataArray = myArray[indexPath.row]
cell.nameLabel.text = "\(dataArray[0])"
cell.ageLabel.text = "\(dataArray[1])"
return cell
}
}
I am trying to add a cell to my table view with a button. Everything I have read and watched suggests that what I have written should work, but it doesn't. Any suggestions?
import UIKit
class RootViewController: UITableViewController, UITableViewDataSource, UITableViewDelegate {
private var cellPointSize: CGFloat!
private var albumsList: AlbumList!
private var albums:[Album]!
private let albumCell = "Album"
#IBOutlet var myTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
let preferredTableViewFont = UIFont.preferredFontForTextStyle(UIFontTextStyleHeadline)
cellPointSize = preferredTableViewFont.pointSize
albumsList = AlbumList.sharedAlbumList
albums = albumsList.albums
self.myTableView.dataSource = self
self.myTableView.delegate = self
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
}
// MARK: - Table view data source
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of rows in the section.
return albums.count
}
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "Albums"
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = myTableView.dequeueReusableCellWithIdentifier(albumCell, forIndexPath: indexPath) as! UITableViewCell
//cell.textLabel?.font = fontForDisplay(atIndexPath: indexPath)
cell.textLabel?.text = albums[indexPath.row].name
cell.detailTextLabel?.text = albums[indexPath.row].artist
return cell
}
#IBAction func addNewAlbumAction(sender: UIBarButtonItem) {
var newAlbum = Album(nameIn: "New Title", yearIn: "New Year", artistIn: "New Artist", labelIn: "New Label")
albumsList.addAlbum(newAlbum)
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.myTableView.reloadData()
})
}
func saveData(albumObject: Album) {
var archiveArray = NSMutableArray(capacity: albums.count)
for a in albums {
var albumEncodedObject = NSKeyedArchiver.archivedDataWithRootObject(a)
archiveArray.addObject(albumEncodedObject)
}
var userData = NSUserDefaults()
userData.setObject(archiveArray, forKey: "albums")
userData.synchronize()
}
My albums array is adding the data correctly. I can see the albums in the debugger. The delegate methods are never being called after the first time when the app loads. Any ideas?
in tableView:numberOfRowsInSection:, it returns albums.count
but when the button is pressed, you add the new album to albumsList
The problem is, albums will not get update.
So I think you should return albumsList.albums.count instead.
and in tableView:cellForRowAtIndexPath:, you modify the cell correspond to albumsList.albums[indexPath.row]
I have an issue with UITableView inserted in a UITableViewCell. This is my custom cell:
Everything works fine for the first, second and third cells, but from the fourth cell for the content of the UITableView inserted in cell is used always the same rows of the first, second and third cells alternatively. Instead the labels outside the UITableView are correctly displayed in every cells. This is my code for the custom cell class:
import UIKit
class SimulazioneQuestionTableViewCell: UITableViewCell, UITableViewDelegate, UITableViewDataSource {
let cellIdentifier = "simRisposteCell"
var arrayRisposte = [Risposta]()
#IBOutlet var numeroLabel: UILabel!
#IBOutlet var domandaLabel: UILabel!
#IBOutlet var risposteTableView: UITableView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
var nib = UINib(nibName: "SimulazioneQuestionAnswerTableViewCell", bundle: nil)
self.risposteTableView.registerNib(nib, forCellReuseIdentifier: self.cellIdentifier)
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayRisposte.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as SimulazioneQuestionAnswerTableViewCell
cell.textLabel?.text = arrayRisposte[indexPath.row].testo
return cell
}
}
And this is my view controller:
import UIKit
class SimulazioneViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var areaSimulazione: Int = Int()
var arrayDomande = [Domanda]()
var arrayRisposte = [[Risposta]]()
var cellIdentifier = "domandaSimulazioneCell"
#IBOutlet var tempoTrascorso: UILabel!
#IBOutlet var simulazioneTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
arrayDomande = ModelManager.instance.getSimulazione(area: areaSimulazione)
var nib = UINib(nibName: "SimulazioneQuestionTableViewCell", bundle: nil)
self.simulazioneTableView.registerNib(nib, forCellReuseIdentifier: self.cellIdentifier)
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayDomande.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: SimulazioneQuestionTableViewCell = simulazioneTableView.dequeueReusableCellWithIdentifier(self.cellIdentifier) as SimulazioneQuestionTableViewCell
var domanda: Domanda = arrayDomande[indexPath.row]
var rispXDomanda = ModelManager.instance.getAnswersForQuestion(domanda.numero)
cell.numeroLabel.text = String(domanda.numero)
cell.domandaLabel.text = domanda.testo
cell.arrayRisposte = rispXDomanda
return cell
}
Some advice to resolve this issue?
Thank you guys!
I never had the idea of putting a UITableView inside a UITableViewCell and therefore would have approached this from a different direction. I'm not saying the table inside a cell is impossible or a bad idea, but the following approach might actually be easier.
My understanding is that your table view shows a number of questions, and each question has possible answer right below it.
I'd use one section per question, with the first row using a custom cell that shows the numeroLabel and the domandaLabel (basically SimulazioneQuestionTableViewCell without the table), and then put the answers into the remaining rows for the section.
private let QuestionCellIdentifier = "QuestionCell"
private let AnswerCellIdentifier = "AnswerCell"
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return arrayDomande.count
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let rispXDomanda = ModelManager.instance.getAnswersForQuestion(domanda.numero)
return 1 + rispXDomanda.count // one extra for the question
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let domanda = arrayDomande[indexPath.section]
switch indexPath.row {
case 0:
let cell = tableView.dequeueReusableCellWithIdentifier(QuestionCellIdentifier) as SimulazioneQuestionTableViewCell
cell.numeroLabel.text = String(domanda.numero)
cell.domandaLabel.text = domanda.testo
return cell
default:
let cell = tableView.dequeueReusableCellWithIdentifier(AnswerCellIdentifier) as SimulazioneQuestionAnswerTableViewCell
let rispXDomanda = ModelManager.instance.getAnswersForQuestion(domanda.numero)
cell.textLabel?.text = rispXDomanda[indexPath.row - 1].testo
return cell
}
It might be a good idea to cache the answers that you get from ModelManager. It depends on how expensive it is to get them - with the code above getAnswersForQuestion() will be called a lot.
Edit: I personally like the .Grouped style for the table view. Using a section per question will nicely separate them visually.
I'm trying to make a view controller that has one text field that populates the tableview below, ideally the user will be able to continue to add to the tableview without jumping between two views.
I previously had it working with the text field on one view that populates a UITableView and used prepareForSegue to push the data to the table, but I haven't been able to get it to work with just one view.
Can anyone please point out where I'm going wrong or push me to a tutorial / documentation to help?
Edit: Clarity
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {
#IBOutlet var tableView: UITableView!
#IBOutlet weak var textField: UITextField!
var items: [String] = ["Pls", "work", "pls", "work", "pls"]
var foodGroup: FoodGroup = FoodGroup(itemName:"")
//var foodGroup: [FoodGroup] = []
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items.count;
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
cell.textLabel.text = self.items[indexPath.row]
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
println("Selected cell #\(indexPath)")
}
func addFood(sender: AnyObject!) {
if (countElements(self.textField.text) > 0) {
self.foodGroup = FoodGroup(itemName: self.textField.text)
}
}
#IBAction func addFoodToList() {
let source = FoodGroup
let foodGroup:FoodGroup = source.foodGroup
if foodGroup.itemName != "" {
self.foodGroup.append(foodGroup)
self.tableView.reloadData()
}
}
}
It seems like your intention here is to have your dataSource be an array of FoodGroup objects. If this is indeed the case you can get rid of your foodGroup instance variable and update your items definition to be like so:
var items = [FoodGroup]()
then in addFoodToList:
if self.textField.text != "" {
let foodGroup = FoodGroup(itemName: self.textField.text)
self.items.append(foodGroup)
self.tableView.reloadData()
}
and finally in cellForRowAtIndexPath:
var cell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
let foodGroup = self.items[indexPath.row] as FoodGroup
cell.textLabel.text = foodGroup.itemName
return cell
Also I don't quite see the intention of your the addFood(sender: AnyObject!) function. Looks like cruft. I would get rid of it. Good luck!