Swift: UITableView? does not have a member named reloadData - ios

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()
}

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

UITableViewController showing white blank screen in simulator

I am trying to make a very simple iOS app that has begins at one UITableViewController and when you click on each cell (a different manner kids should learn) it pushes that specific data to a UIViewController. I have added placeholder information in the cells, but when I run the simulator only a blank screen shows up. I attach pictures and code below.
class TableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func backBtn(_ sender: AnyObject) {
dismiss(animated: true, completion: nil);
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 0
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 0
}
}
class ViewController: UIViewController, UITableViewDelegate {
#IBOutlet var tableView: UITableView!
var names = ["Manner 1", "Manner 2", "Manner 3", "Manner 4", "Manner 6", "Manner 7", "Manner 8"]
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 8
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = self.tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath as IndexPath) as! Manner2Cell
cell.name.text = names[indexPath.row]
return cell
}
}
//Manner2Cell actually refers to the first cell. I know I know bad naming convention.
class Manner2Cell: UITableViewCell {
#IBOutlet weak var name: UILabel!
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
}
}
Looking at all of this it looks like I have some repeated code. I feel like this is an easy fix but I just can't figure it out!
You have to set your ViewController as a dataSource for your tableView and adopt the protocol UITableViewDataSource.
class ViewController: UITableViewDelegate, UITableViewDataSource, ... {
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self // Assigns ViewController as delegate for tableView
tableView.dataSource = self
}
The scene in the upper left of your Interface Builder screen snapshot looks like a UITableViewController (which is presumably the class you call TableViewController).
But your numberOfSections and numberOfRowsInSection both return zero. So you'll have a blank white screen. Frankly, it looks like the code intended for the first scene's UITableViewController subclass has been put in the second scene's view controller.
Your second scene (upper right of your snapshot) is a little confusing, because it looks like that's a UITableViewController, too, but it doesn't look like it should be a table at all. I'm not sure what you're trying to do there. Is it really a table with repeated occurrences or is it just supposed to be the details of the cell you selected in the first scene? If it's just supposed to be a "details" screen, then that should be a simple UIViewController, not a UITableViewController.

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
}

Missing init codes in .swift files

I have been trying to learn to do the UITableView Custom Cells and have been looking up examples on youtube. However they always come up with an error when I run them.
I was looking at this video https://www.youtube.com/watch?v=rIRvqRzOa-s and I noticed that when they first created a new .swift file it had this code:
init(style: UITableViewStyle){
super.init(style: style)}
When I created my .swift file it did not have this in it. I am wondering if this is why my tableviews are not running. I am currently using Xcode 6.1.1. I had tried to just type the code in as well but that didn't work either. Anyway to fix this or is it a bug?
EDIT:
so the full code I used for maintableviewcontroller.swift:
import UIKit
var ArrayObject = ArrayData()
class MainTableViewController: UITableViewController
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return ArrayObject.MyArray().count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:MyCustomTableViewCell = tableView .dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as MyCustomTableViewCell
cell.LabelForDisplay.text = ArrayObject.MyArray().objectAtIndex(indexPath.row) as String
return cell
}
}
Mycustomtablecell.swift:
import UIKit
class MyCustomTableViewCell: UITableViewCell {
#IBOutlet var LabelForDisplay: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
and ArrayData.swift:
import UIKit
class ArrayData: NSObject {
func MyArray() -> NSMutableArray
{
var Arraydatas:NSMutableArray = ["Effect Works", "NPN Labs", "Alvin", "Varghese"]
return Arraydatas
}
}
the error I was getting was "thread 1 sigterm"
When you want to create an UITableViewController instead of selecting File > New > File... > Swift File
do File > New > File... > Cocoa Touch Class > Class: MainTableViewController > Subclass of: UITableViewController
This way you will have all the necessary code to start, no need to copy it from tutorials.

Why my simple tableview app won't work?

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?

Resources