Reputation: 127
I have a text field that when I type a word in, and then press a button is supposed to add the word the the tableview. I know the array is being updated because after the button is pressed, the array, with its new value print fine in the console. I've tried reloadData() in several places but it's not doing anything. Here is my code:
import UIKit
class Arraytest: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var textField: UITextField?
var names = ["Jack", "Andy", "Guy", "Bruce", "Nick", "James", "Dominick"]
@IBAction func addButton(_ sender: Any) {
let name : String = textField!.text!
names.append(name)
textField?.text! = ""
for guy in names{
**print(guy)**
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "Cell")
cell.textLabel?.text = names[indexPath.row]
***tableView.reloadData()***
return cell
}
}
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return names.count
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "Cell")
cell.textLabel?.text = names[indexPath.row]
return cell
}
}
Let's say I type John in the text field, here is what the console prints:
Jack
Andy
Guy
Bruce
Nick
James
Dominick
John
I know the array works fine, but not why the tableView won't reload when everyone claims reloadData() works(I'm sure it does, and I'm just making an easy mistake!)..Any ideas?
EDIT: Ok it turns out that you do have to drag the IBOutlet from the tableview. The reason I didn't do this earlier was because I watched a video and his worked without making the connection.
Upvotes: 1
Views: 10603
Reputation: 127
Drag a connection from a split view controller to your view controller and use reloadData().
Upvotes: 0
Reputation: 1760
You should learn more about table view & how it works. Please see Apple Documentation Creating and Configuring a Table View
Here the method cellForRowAt
is a data source of table view and it's get fired from tableview automatically when it's need to populate cell data. You couldn't manually call this method. Implementing this method inside @IBAction func addButton()
does nothing. Function always needs to call from another method. So you should remove cellForRowAt
inside @IBAction func addButton()
.
Solution: Get an table view outlet from storyboard. If need help see here Connect the UI to Code
@IBOutlet weak var tableView: UITableView?
Then set tableview datasource and delegate in viewDidLoad()
override func viewDidLoad() {
super.viewDidLoad()
tableView?.dataSource = self;
tableView?.delegate = self;
}
And finally update @IBAction func addButton()
as below
@IBAction func addButton(_ sender: Any) {
let name : String = textField!.text!
names.append(name)
textField?.text! = ""
for guy in names{
print(guy)
}
tableView?.reloadData()
}
Full source may look like this:
import UIKit
class Arraytest: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var textField: UITextField?
@IBOutlet weak var tableView: UITableView?
var names = ["Jack", "Andy", "Guy", "Bruce", "Nick", "James", "Dominick"]
override func viewDidLoad() {
super.viewDidLoad()
tableView?.dataSource = self;
tableView?.delegate = self;
}
@IBAction func addButton(_ sender: Any) {
let name : String = textField!.text!
names.append(name)
textField?.text! = ""
for guy in names{
**print(guy)**
}
tableView?.reloadData()
}
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return names.count
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "Cell")
cell.textLabel?.text = names[indexPath.row]
return cell
}
}
Upvotes: 4
Reputation: 1477
Your code has two very big mistakes (assuming that your tableview delegates are connected to your viewcontroller correctly).
First your a missing an IBOulet
reference to your tableview
. Create one and you can call the reloadData()
method in that outlet.
Second, you should not call the public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
delegate method inside your IBAction
. It is a delegate method, it is already listening for an event or command that will fire its logic, in this case reloadData()
.
So your IBaction
should only take the value from the textfield
and add it to the array, to finally call reloadData()
, which will call public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
this code works... hope it helps:
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableview: UITableView!
@IBOutlet weak var textField: UITextField?
var names = ["Jack", "Andy", "Guy", "Bruce", "Nick", "James", "Dominick"]
// MARK: tableview delegate methods
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return names.count
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "Cell")
cell.textLabel?.text = names[indexPath.row]
return cell
}
// MARK: ibactions
@IBAction func addButton(_ sender: Any) {
let name : String = textField!.text!
names.append(name)
textField?.text! = ""
tableview.reloadData()
}
}
Upvotes: 2
Reputation: 2034
You have to remove TableView delegate method from
@IBAction func addButton(_ sender: Any) {
}
method & put it outside of it. Create a property of this tableView form storyboard like that
@IBOutlet weak var tableView: UITableView!
In viewDidload method set datasource & delegate of it like that
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.datasource = self
self.tableView.delegate = self
}
Hope it helps.
Upvotes: 2
Reputation: 11
You have to take your tableview func outside the @IBAction func addButton, as it's part of the uitableviewdatasource and is required to display your cell. After that, all you need is to put tableView.reloadData()
after the for guy in names{ ... }
loop.
Upvotes: 0
Reputation: 571
You can achieve this by adding a property observer to the array of names. The didset method will run if there is any changes to the value.
class Arraytest: UIViewController, UITableViewDelegate UITableViewDatasource {
var names = ["Jack", "Andy", "Guy", "Bruce", "Nick", "James", "Dominick"] {
didSet {
self.tableView.reloadData();
}
}
}
The tableview func inside the addButton func doesnt run.. remove it and keep it like this:
@IBAction func addButton(_ sender: Any) {
let name : String = textField!.text!
names.append(name)
textField?.text! = ""
for guy in names{
**print(guy)**
}
}
Upvotes: 0