Reputation: 544
I have a UITableViewController
:
class MyMenuTableViewController: UITableViewController, UITableViewDataSource, UITableViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
func updateFirstMenuRow() {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
println("tableview is \(self.tableView)")
var indexPath = NSIndexPath(forRow: 0, inSection: 0)
var cell = self.tableView.cellForRowAtIndexPath(indexPath)
var rand = arc4random()
cell!.textLabel!.text = "\(rand)"
cell!.setNeedsLayout()
cell!.setNeedsDisplay()
println("cell is \(cell)")
println("rand is \(rand)")
println("textLabel.text is \(cell!.textLabel!.text!)")
})
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// Return the number of sections.
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of rows in the section.
return 3
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("CELL") as? UITableViewCell
if (cell == nil) {
cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "CELL")
}
switch indexPath.row {
case 0:
cell!.textLabel?.text = "This is the old text"
case 1:
cell!.textLabel?.text = "Foo"
case 2:
cell!.textLabel?.text = "Bar"
default:
cell!.textLabel?.text = "UNDEFINED"
}
return cell!
}
}
Note that I have a function updateFirstMenuRow()
where I'll update the textLabel.text of the first tableView row with a different value (in my text case, a different number).
I need to run updateFirstMenuRow()
from another class, like below:
class MyOtherClass:UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
MyMenuTableViewController().updateFirstMenuRow()
}
//.....
}
It will show all println
in the console, however it does not update the the cell.textLabel.text with a random number.
In console, I can see that:
tableView is NOT nil
cell is NOT nil
rand is always a different random number
textLabel.text returns (strangely enough) the always updated random number (rand)
However, the actual textLabel.text in the MyMenuTableViewController
is never updated, and stays at it's initial value, "This is the old text"
.
When I try to run updateFirstMenuRow()
within UITableViewController
, it will work - meaning, it will update the textLabel.text of the first row in the tableView:
class MyMenuTableViewController: UITableViewController, UITableViewDataSource, UITableViewDelegate {
override func viewDidAppear(animated: Bool) {
updateFirstMenuRow()
}
}
Note that I'm trying to run the update functions from the main thread, as suggested by other stackoverflow questions. However, no success.
I have been struggling with this for several hours now, I'd be glad if anyone can give me some pointers as for why my update function will not properly run - my guess is that it doesn't have "write access" to the tableView
in MyMenuTableViewController
. Thanks a lot in advance!
Upvotes: 1
Views: 1351
Reputation: 544
I managed to solve my problem thanks to Paul's answer.
I am in fact using a delegate, which is triggered in the MyOtherClass
, to "forward" the command to update the textLabel.text - however, I managed to get the correct reference.
Before, I was using MyMenuTableViewController()
twice
Now I am using var menuTableViewController:MyMenuTableViewController?
, then I set the value once with self.menuTableViewController = MyMenuTableViewController()
and then subsequently I use menuTableViewController!
or menuTableViewController!.updateFirstMenuRow()
, so I always update the tableView in the "same" instance of MyMenuTableViewController
.
Upvotes: 0
Reputation: 114865
This
MyMenuTableViewController().updateFirstMenuRow()
creates a new instance of MyMenuTableViewController
- so the method is executed on an instance that isn't on screen. This is why you see the output of the println
but no change in the tableview.
You need to pass a reference to the MyMenuTableViewController
instance to the MyOtherClass
instance. You need to add a property to MyOtherClass
to hold the reference -
menuTableViewController:MyMenuTableViewController?
You don't show how you get from one to the other, but, for example if it was via a segue you would use the following -
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if (segue.identifier == "someIdentifier") {
let destinationVC = segue.destinationViewController as MyOtherClass
destinationVC.menuTableViewController = self
}
}
Then in your MyOtherClass
you can say -
if (self.menuTableViewController != nil) {
self.menuTableViewController!.updateFirstMenuRow()
}
Upvotes: 1