Why my simple tableview app won't work? - ios

Iv'e made a code for a simple tableview app and with textfield and a button.
When I click on the button it adds to the array but do not show it on the table view.
What can I do to see it?
Here is the code:
import UIKit
class ViewController: UIViewController, UITableViewDelegate {
#IBOutlet weak var textfieldd: UITextField!
#IBOutlet var tasksTable:UITableView!
var toDoList:[String] = []
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.
}
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
return toDoList.count
}
#IBAction func Add(sender: AnyObject) {
toDoList.append(textfieldd.text)
println(toDoList)
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
var cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
cell.textLabel?.text = toDoList[indexPath.row]
return cell
}
}

You've updated your data source (the array), but not the actual display (the table view). You should call the reloadData() function whenever you want to update your table view:
tasksTable.reloadData()

You need to reload the TableView after you've added the new element to the list.
You can do so with the reloadData method.
tasksTable.reloadData()

You are not applying the UITableviewDataSource protocol to your class, just the delegate.
Add it and set the datasource for the table to the class?

Related

UITableView always displays basic cell instead of custom cell in Swift

I spent hours of trying to fix this, but my simple app still displays the basic cell type instead of my prototype cell. I'm aware of using the identifier and registering after loading up the view, but it still displays the basic cells with just one label.
Here is my code so far:
My prototype is using this UITableViewCell:
class CoinTableViewCell: UITableViewCell {
#IBOutlet weak var coinIcon: UIImageView!
#IBOutlet weak var coinTitleLabel: UILabel!
#IBOutlet weak var holdings: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
UITableViewController:
class CoinTableViewController: UITableViewController {
var coins = ["Coin1","Coin2","Coin3"]
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.register(CoinTableViewCell.self, forCellReuseIdentifier: "currency_cell")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return coins.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:CoinTableViewCell! = self.tableView.dequeueReusableCell(withIdentifier: "currency_cell", for: indexPath) as! CoinTableViewCell
let coinName = coins[indexPath.row]
cell.coinTitleLabel?.text = coinName
return cell!
}
}
I would be so grateful if someone is able the help me out with this!
You are creating your custom cell directly on the tableview in the storyboard, right ?
If this is the case then you don't need to register the cell in your viewDidLoad as the storyboard takes care of that. You just deque it and it's good to go.
If you register it manually you just override what the storyboard did and end up getting a regular cell as the cell gets instantiated from the code instead of getting instantiated from the storyboard.
Cheers

Table view not working

I get an error by the IBoutlet of tableView saying "cannot override with stored property "tableView"". I'm not quite sure what this means, any type of help will be appreciated.
import UIKit
class UsersViewController: UITableViewController {
#IBOutlet var tableView: UITableView!
var users = ["Marc", "Mark" , "Louise", "Ahinga", "Amossi", "Kalenga"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView:UITableView, numberOfRowsInSection section:Int) -> Int {
return 3
}
override func tableView(tableView:UITableView, cellForRowAtIndexPath indexPath:NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! userCell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
}
}
A UITableViewController comes with a UITableView built in, aptly named tableView. In the code you pasted you are adding an extra UITableView to it and giving it the same name. That's what the compiler is complaining about.
In theory, when you are using a plain vanilla UITableViewController from the storyboard you should not link the table to an IBOutlet. That's taken care of.
If you are building something more sophisticated that needs an extra UITableViewController on top of the one that the class provides in storyboard, then you should name it differently.
you have to set as it's delegate and dataSource in viewDidLoad() like this
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
self.tableView.dataSource = self
}

Swift - TableView of steppers, click one stepper in a cell and other steppers get activated?

I am new to IOS and basically I have a tableView and whenever it has 40 cells and each cell has a stepper and a label. the label displays the stepper's value. The tableview generates the cells fine, but the problem is that whenever I click the stepper in one cell, some other random cells also have their steppers activated.This is swift by the way. Here is the code for the cell:
import UIKit
class StudentTableViewCell: UITableViewCell {
#IBOutlet weak var studentNameAndValue: UILabel!
#IBOutlet weak var studentValueChanger: UIStepper!
let name:String?
let value:Int?
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
}
#IBAction func stepperValueChanged(sender: AnyObject) {
studentNameAndValue.text = "\(name): \(Int(studentValueChanger.value))"
}
}
Here is the code for the viewcontroller:
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
tableView.delegate = self
tableView.dataSource = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 40
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("studentCell") as StudentTableViewCell
return cell
}
}
The problem is in your table view controller. It would be better to put the value-changed method there. Alternatively, review your cellForRowAtIndexPath method. You are not updating the cells correctly when they are recycled.
You have to set the value of stepper and label explicitly in cellForRowAtIndexPath. You cannot read these values from the cell - they should be in your datasource (i.e. the table view controller should know what to display for a given index path).
Connect the stepper handler to the method in the view controller, then identify the proper index path via the sender argument.
#IBAction func stepperChanged(sender: UIStepper) {
let point = sender.convertPoint(CGPointZero, toView: tableView)
let indexPath = self.tableView.indexPathForRowAtPoint(point)!
let myData = dataArray[indexPath.row] // or whatever your datasource
// if you need to update the cell
let cell = self.tableView.cellForRowAtIndexPath(indexPath)
}

Swift: UITableView? does not have a member named reloadData

I'm doing a basic intro to Swift course, and keep getting stuck on this 'to-do list' app task.
I've had to put a ? after creating an IB OUtlet ( #IBOutlet var tasksTable:UITableView? ) to stop it from crashing, but this has meant that I've got the error 'UITableView? does not have a member named reloadData' after this function:
override func viewWillAppear(animated: Bool) {
tasksTable.reloadData()
Anyone know what's going on here? Apologies for the simple question - I'm pretty new to this.
p.s I'm using Swift 6.1
Full code is below.
Thanks in advance.
import UIKit
var toDoItems :[String] = []
class FirstViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var tasksTable:UITableView?
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.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return toDoItems.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cell")
cell.textLabel.text = "Example"
return cell
}
override func viewWillAppear(animated: Bool) {
tasksTable.reloadData()
}
tasksTable in an optional, so you should use optional chaining and write tasksTable?.reloadData(). Since after awakeFromNib, tasksTable will always be non-nil, you can also type your outlet UITableView! to avoid this.
Write it like this:
override func viewWillAppear(animated: Bool) {
tasksTable?.reloadData()
}

Table view displays limited number of cells?

I want to display 128 cells in the table view. However, due to some reason the table view displays a maximum of five cells. I checked the number of rows returned by the code, it is greater than 5. So I am sure that part is correct. Also, I have written code for custom cell. Does this contribute to this behavior? If yes, what should I do ? If no, what am I doing wrong ?
/* Custom cell code */
class myCustomCell: UITableViewCell{
#IBOutlet var myTitle: UILabel!
#IBOutlet var mySubtitle: UILabel!
convenience required init(reuseIdentifier: String!){
self.init(style: UITableViewCellStyle.Value1, reuseIdentifier: reuseIdentifier )
}
}
/* code for table view */
import Foundation
import UIKit
import CoreLocation
class TableViewController: UITableViewController{
var rowNumber: String!
override func viewDidLoad() {
super.viewDidLoad()
//println("Count is : \(dataArray.count)")
// 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.
}
override func numberOfSectionsInTableView(tableView: UITableView!) -> Int {
return 1;
}
override func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
//println("Here Count is : \(dataArray.count)")
return dataArray.count
}
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
let cellId = "cell"
var cell = tableView.dequeueReusableCellWithIdentifier(cellId) as? myCustomCell
//UITableViewCell
if nil==cell {
cell = myCustomCell(reuseIdentifier: cellId)
}
if let ip = indexPath{
var dict: NSDictionary! = dataArray.objectAtIndex(indexPath.row) as NSDictionary
cell!.myTitle.text = dict.objectForKey("name") as String
}
return cell
}
override func tableView(tableView: UITableView!, didSelectRowAtIndexPath: NSIndexPath){
//println("Clicked \(didSelectRowAtIndexPath.row)")
}
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if(segue.identifier == "centerDetails"){
var svc = segue!.destinationViewController as CellClickController
var selectIndex = self.tableView.indexPathForCell(sender as UITableViewCell)
svc.cellIdx = selectIndex.row
}
}
}
Thanks!
The UITableView method dequeueReusableCellWithIdentifier is why only 5-ish cells are instantiated at one time. The UITableView only creates enough UITableViewCell objects are to fill the screen. When one scrolls off and is no longer in view, it is queued for reuse. If you are scrolling quickly, it may create more cells than the screen needs, but generally it will use just enough to cover the screen.
You can create a new UITableViewCell for each index path you display. However it will go out of scope when it scrolls offscreen unless you retain the object reference yourself. You can do this by adding it to an array that your class manages.

Resources