Swift IOS Issues updating Label in DetailView from MasterView










0















My first posting on stackoverflow, so sorry if its not right



I am using the Master/Detail View template in XCode. This is a BLT Central app and it gets notified of events happening on the BLE device.
I have a Master view, this is updated using



 public func UpdateView() 
tableView.beginUpdates()
tableView.reloadRows(at: self.tableView.indexPathsForVisibleRows!, with: .none)
tableView.endUpdates()



This works fine and the TableView shows the updates live whenever the BLE notifies



However I also want to update the detail view live, incase this is being shown.



I have the label linked in the DetailView via:



@IBOutlet weak var detailDescription: UILabel!


And it updates just fine when the MasterView seques to the DetailView



However if I try to update the Label when the BLE notify arrives the @IBOutlet detailDescription has turned to nil, so the update fails (Label not linked)



func UpdateDetail() 
guard let label = detailDescription else
return; //Label not linked

label.text = "New Data"



The UpdateDetail() function is also used in viewDidLoad() and in that case its working fine



Whats really weird is that if I add a timer in the DetailView to just do the update



 var timer : Timer? = nil

@objc func fireTimer()
DispatchQueue.main.async
self.UpdateDetail()




It works fine, so its possibly something to do with calling the UpdateDetail() function from outside the Detail class.



I have checked if the detailDescription reference gets reset by adding a didSet to the property, and its only called once when the view is loaded



Guess I could use the timer work around, but I am totally baffled why the detailItem appears as nil sometimes, so would be grateful for a sanity check.



UPDATE Gone back to basics_______



So I have now gone back to the standard Apple Master->Detail view template and added a simple timer which updates the list. The ListView updates fine, however it still does not update the detail view dynamically. outside its own class.



I am using on a 1 second timer after MainView is loaded, the list view updates fine, however the detail does not.



When debugging it steps into configureView() fine, but detailDescriptionLabel is nil after the first viewDidLoad()



Have tried all the suggestions below, however in each case the weak reference to the label is nil after the initial Load



Totally baffled



 @objc func doTimer() 
for index in 0..<objects.count
objects[index]=(objects[index] as! NSDate).addingTimeInterval(1)

tableView.beginUpdates()
tableView.reloadRows(at: self.tableView.indexPathsForVisibleRows!, with: .none)
tableView.endUpdates()
DispatchQueue.main.async
self.detailViewController?.configureView()




Full code for MasterViewController.swift here, rest is the same as standard template.



import UIKit

class MasterViewController: UITableViewController

var detailViewController: DetailViewController? = nil
var objects = [Any]()



override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
navigationItem.leftBarButtonItem = editButtonItem

let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(insertNewObject(_:)))
navigationItem.rightBarButtonItem = addButton
if let split = splitViewController
let controllers = split.viewControllers
detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController

//Added timer here
_ = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(doTimer), userInfo: nil, repeats: true)


//Update data in list
@objc func doTimer()
for index in 0..<objects.count
objects[index]=(objects[index] as! NSDate).addingTimeInterval(1)

tableView.beginUpdates()
tableView.reloadRows(at: self.tableView.indexPathsForVisibleRows!, with: .none)
tableView.endUpdates()
DispatchQueue.main.async
self.detailViewController?.configureView()



override func viewWillAppear(_ animated: Bool)
clearsSelectionOnViewWillAppear = splitViewController!.isCollapsed
super.viewWillAppear(animated)


@objc
func insertNewObject(_ sender: Any)
objects.insert(NSDate(), at: 0)
let indexPath = IndexPath(row: 0, section: 0)
tableView.insertRows(at: [indexPath], with: .automatic)


// MARK: - Segues

override func prepare(for segue: UIStoryboardSegue, sender: Any?)
if segue.identifier == "showDetail"
if let indexPath = tableView.indexPathForSelectedRow
let object = objects[indexPath.row] as! NSDate
let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
controller.detailItem = object
controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
controller.navigationItem.leftItemsSupplementBackButton = true




// MARK: - Table View

override func numberOfSections(in tableView: UITableView) -> Int
return 1


override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return objects.count


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

let object = objects[indexPath.row] as! NSDate
cell.textLabel!.text = object.description
return cell


override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool
// Return false if you do not want the specified item to be editable.
return true


override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath)
if editingStyle == .delete
objects.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
else if editingStyle == .insert
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.













share|improve this question
























  • Where do you call the UpdateDetail method in the non-timer version? Is it called on UI thread?

    – Peter Pajchl
    Nov 13 '18 at 11:11











  • Yes, I added DispatchQueue.main.async self.detailViewController?.UpdateDetail()

    – Richard Leinfellner
    Nov 13 '18 at 18:32












  • Hello there and welcome on board. Do you have a link to the project?

    – Lausbert
    Nov 13 '18 at 20:08











  • github.com/RLTeachGit/DetailViewIssue.git I have uploaded it here

    – Richard Leinfellner
    Nov 13 '18 at 20:37












  • Unrelated but begin-/endUpdates() has no effect at all when reloading rows or data.

    – vadian
    Nov 14 '18 at 9:53
















0















My first posting on stackoverflow, so sorry if its not right



I am using the Master/Detail View template in XCode. This is a BLT Central app and it gets notified of events happening on the BLE device.
I have a Master view, this is updated using



 public func UpdateView() 
tableView.beginUpdates()
tableView.reloadRows(at: self.tableView.indexPathsForVisibleRows!, with: .none)
tableView.endUpdates()



This works fine and the TableView shows the updates live whenever the BLE notifies



However I also want to update the detail view live, incase this is being shown.



I have the label linked in the DetailView via:



@IBOutlet weak var detailDescription: UILabel!


And it updates just fine when the MasterView seques to the DetailView



However if I try to update the Label when the BLE notify arrives the @IBOutlet detailDescription has turned to nil, so the update fails (Label not linked)



func UpdateDetail() 
guard let label = detailDescription else
return; //Label not linked

label.text = "New Data"



The UpdateDetail() function is also used in viewDidLoad() and in that case its working fine



Whats really weird is that if I add a timer in the DetailView to just do the update



 var timer : Timer? = nil

@objc func fireTimer()
DispatchQueue.main.async
self.UpdateDetail()




It works fine, so its possibly something to do with calling the UpdateDetail() function from outside the Detail class.



I have checked if the detailDescription reference gets reset by adding a didSet to the property, and its only called once when the view is loaded



Guess I could use the timer work around, but I am totally baffled why the detailItem appears as nil sometimes, so would be grateful for a sanity check.



UPDATE Gone back to basics_______



So I have now gone back to the standard Apple Master->Detail view template and added a simple timer which updates the list. The ListView updates fine, however it still does not update the detail view dynamically. outside its own class.



I am using on a 1 second timer after MainView is loaded, the list view updates fine, however the detail does not.



When debugging it steps into configureView() fine, but detailDescriptionLabel is nil after the first viewDidLoad()



Have tried all the suggestions below, however in each case the weak reference to the label is nil after the initial Load



Totally baffled



 @objc func doTimer() 
for index in 0..<objects.count
objects[index]=(objects[index] as! NSDate).addingTimeInterval(1)

tableView.beginUpdates()
tableView.reloadRows(at: self.tableView.indexPathsForVisibleRows!, with: .none)
tableView.endUpdates()
DispatchQueue.main.async
self.detailViewController?.configureView()




Full code for MasterViewController.swift here, rest is the same as standard template.



import UIKit

class MasterViewController: UITableViewController

var detailViewController: DetailViewController? = nil
var objects = [Any]()



override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
navigationItem.leftBarButtonItem = editButtonItem

let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(insertNewObject(_:)))
navigationItem.rightBarButtonItem = addButton
if let split = splitViewController
let controllers = split.viewControllers
detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController

//Added timer here
_ = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(doTimer), userInfo: nil, repeats: true)


//Update data in list
@objc func doTimer()
for index in 0..<objects.count
objects[index]=(objects[index] as! NSDate).addingTimeInterval(1)

tableView.beginUpdates()
tableView.reloadRows(at: self.tableView.indexPathsForVisibleRows!, with: .none)
tableView.endUpdates()
DispatchQueue.main.async
self.detailViewController?.configureView()



override func viewWillAppear(_ animated: Bool)
clearsSelectionOnViewWillAppear = splitViewController!.isCollapsed
super.viewWillAppear(animated)


@objc
func insertNewObject(_ sender: Any)
objects.insert(NSDate(), at: 0)
let indexPath = IndexPath(row: 0, section: 0)
tableView.insertRows(at: [indexPath], with: .automatic)


// MARK: - Segues

override func prepare(for segue: UIStoryboardSegue, sender: Any?)
if segue.identifier == "showDetail"
if let indexPath = tableView.indexPathForSelectedRow
let object = objects[indexPath.row] as! NSDate
let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
controller.detailItem = object
controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
controller.navigationItem.leftItemsSupplementBackButton = true




// MARK: - Table View

override func numberOfSections(in tableView: UITableView) -> Int
return 1


override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return objects.count


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

let object = objects[indexPath.row] as! NSDate
cell.textLabel!.text = object.description
return cell


override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool
// Return false if you do not want the specified item to be editable.
return true


override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath)
if editingStyle == .delete
objects.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
else if editingStyle == .insert
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.













share|improve this question
























  • Where do you call the UpdateDetail method in the non-timer version? Is it called on UI thread?

    – Peter Pajchl
    Nov 13 '18 at 11:11











  • Yes, I added DispatchQueue.main.async self.detailViewController?.UpdateDetail()

    – Richard Leinfellner
    Nov 13 '18 at 18:32












  • Hello there and welcome on board. Do you have a link to the project?

    – Lausbert
    Nov 13 '18 at 20:08











  • github.com/RLTeachGit/DetailViewIssue.git I have uploaded it here

    – Richard Leinfellner
    Nov 13 '18 at 20:37












  • Unrelated but begin-/endUpdates() has no effect at all when reloading rows or data.

    – vadian
    Nov 14 '18 at 9:53














0












0








0








My first posting on stackoverflow, so sorry if its not right



I am using the Master/Detail View template in XCode. This is a BLT Central app and it gets notified of events happening on the BLE device.
I have a Master view, this is updated using



 public func UpdateView() 
tableView.beginUpdates()
tableView.reloadRows(at: self.tableView.indexPathsForVisibleRows!, with: .none)
tableView.endUpdates()



This works fine and the TableView shows the updates live whenever the BLE notifies



However I also want to update the detail view live, incase this is being shown.



I have the label linked in the DetailView via:



@IBOutlet weak var detailDescription: UILabel!


And it updates just fine when the MasterView seques to the DetailView



However if I try to update the Label when the BLE notify arrives the @IBOutlet detailDescription has turned to nil, so the update fails (Label not linked)



func UpdateDetail() 
guard let label = detailDescription else
return; //Label not linked

label.text = "New Data"



The UpdateDetail() function is also used in viewDidLoad() and in that case its working fine



Whats really weird is that if I add a timer in the DetailView to just do the update



 var timer : Timer? = nil

@objc func fireTimer()
DispatchQueue.main.async
self.UpdateDetail()




It works fine, so its possibly something to do with calling the UpdateDetail() function from outside the Detail class.



I have checked if the detailDescription reference gets reset by adding a didSet to the property, and its only called once when the view is loaded



Guess I could use the timer work around, but I am totally baffled why the detailItem appears as nil sometimes, so would be grateful for a sanity check.



UPDATE Gone back to basics_______



So I have now gone back to the standard Apple Master->Detail view template and added a simple timer which updates the list. The ListView updates fine, however it still does not update the detail view dynamically. outside its own class.



I am using on a 1 second timer after MainView is loaded, the list view updates fine, however the detail does not.



When debugging it steps into configureView() fine, but detailDescriptionLabel is nil after the first viewDidLoad()



Have tried all the suggestions below, however in each case the weak reference to the label is nil after the initial Load



Totally baffled



 @objc func doTimer() 
for index in 0..<objects.count
objects[index]=(objects[index] as! NSDate).addingTimeInterval(1)

tableView.beginUpdates()
tableView.reloadRows(at: self.tableView.indexPathsForVisibleRows!, with: .none)
tableView.endUpdates()
DispatchQueue.main.async
self.detailViewController?.configureView()




Full code for MasterViewController.swift here, rest is the same as standard template.



import UIKit

class MasterViewController: UITableViewController

var detailViewController: DetailViewController? = nil
var objects = [Any]()



override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
navigationItem.leftBarButtonItem = editButtonItem

let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(insertNewObject(_:)))
navigationItem.rightBarButtonItem = addButton
if let split = splitViewController
let controllers = split.viewControllers
detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController

//Added timer here
_ = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(doTimer), userInfo: nil, repeats: true)


//Update data in list
@objc func doTimer()
for index in 0..<objects.count
objects[index]=(objects[index] as! NSDate).addingTimeInterval(1)

tableView.beginUpdates()
tableView.reloadRows(at: self.tableView.indexPathsForVisibleRows!, with: .none)
tableView.endUpdates()
DispatchQueue.main.async
self.detailViewController?.configureView()



override func viewWillAppear(_ animated: Bool)
clearsSelectionOnViewWillAppear = splitViewController!.isCollapsed
super.viewWillAppear(animated)


@objc
func insertNewObject(_ sender: Any)
objects.insert(NSDate(), at: 0)
let indexPath = IndexPath(row: 0, section: 0)
tableView.insertRows(at: [indexPath], with: .automatic)


// MARK: - Segues

override func prepare(for segue: UIStoryboardSegue, sender: Any?)
if segue.identifier == "showDetail"
if let indexPath = tableView.indexPathForSelectedRow
let object = objects[indexPath.row] as! NSDate
let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
controller.detailItem = object
controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
controller.navigationItem.leftItemsSupplementBackButton = true




// MARK: - Table View

override func numberOfSections(in tableView: UITableView) -> Int
return 1


override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return objects.count


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

let object = objects[indexPath.row] as! NSDate
cell.textLabel!.text = object.description
return cell


override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool
// Return false if you do not want the specified item to be editable.
return true


override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath)
if editingStyle == .delete
objects.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
else if editingStyle == .insert
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.













share|improve this question
















My first posting on stackoverflow, so sorry if its not right



I am using the Master/Detail View template in XCode. This is a BLT Central app and it gets notified of events happening on the BLE device.
I have a Master view, this is updated using



 public func UpdateView() 
tableView.beginUpdates()
tableView.reloadRows(at: self.tableView.indexPathsForVisibleRows!, with: .none)
tableView.endUpdates()



This works fine and the TableView shows the updates live whenever the BLE notifies



However I also want to update the detail view live, incase this is being shown.



I have the label linked in the DetailView via:



@IBOutlet weak var detailDescription: UILabel!


And it updates just fine when the MasterView seques to the DetailView



However if I try to update the Label when the BLE notify arrives the @IBOutlet detailDescription has turned to nil, so the update fails (Label not linked)



func UpdateDetail() 
guard let label = detailDescription else
return; //Label not linked

label.text = "New Data"



The UpdateDetail() function is also used in viewDidLoad() and in that case its working fine



Whats really weird is that if I add a timer in the DetailView to just do the update



 var timer : Timer? = nil

@objc func fireTimer()
DispatchQueue.main.async
self.UpdateDetail()




It works fine, so its possibly something to do with calling the UpdateDetail() function from outside the Detail class.



I have checked if the detailDescription reference gets reset by adding a didSet to the property, and its only called once when the view is loaded



Guess I could use the timer work around, but I am totally baffled why the detailItem appears as nil sometimes, so would be grateful for a sanity check.



UPDATE Gone back to basics_______



So I have now gone back to the standard Apple Master->Detail view template and added a simple timer which updates the list. The ListView updates fine, however it still does not update the detail view dynamically. outside its own class.



I am using on a 1 second timer after MainView is loaded, the list view updates fine, however the detail does not.



When debugging it steps into configureView() fine, but detailDescriptionLabel is nil after the first viewDidLoad()



Have tried all the suggestions below, however in each case the weak reference to the label is nil after the initial Load



Totally baffled



 @objc func doTimer() 
for index in 0..<objects.count
objects[index]=(objects[index] as! NSDate).addingTimeInterval(1)

tableView.beginUpdates()
tableView.reloadRows(at: self.tableView.indexPathsForVisibleRows!, with: .none)
tableView.endUpdates()
DispatchQueue.main.async
self.detailViewController?.configureView()




Full code for MasterViewController.swift here, rest is the same as standard template.



import UIKit

class MasterViewController: UITableViewController

var detailViewController: DetailViewController? = nil
var objects = [Any]()



override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
navigationItem.leftBarButtonItem = editButtonItem

let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(insertNewObject(_:)))
navigationItem.rightBarButtonItem = addButton
if let split = splitViewController
let controllers = split.viewControllers
detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController

//Added timer here
_ = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(doTimer), userInfo: nil, repeats: true)


//Update data in list
@objc func doTimer()
for index in 0..<objects.count
objects[index]=(objects[index] as! NSDate).addingTimeInterval(1)

tableView.beginUpdates()
tableView.reloadRows(at: self.tableView.indexPathsForVisibleRows!, with: .none)
tableView.endUpdates()
DispatchQueue.main.async
self.detailViewController?.configureView()



override func viewWillAppear(_ animated: Bool)
clearsSelectionOnViewWillAppear = splitViewController!.isCollapsed
super.viewWillAppear(animated)


@objc
func insertNewObject(_ sender: Any)
objects.insert(NSDate(), at: 0)
let indexPath = IndexPath(row: 0, section: 0)
tableView.insertRows(at: [indexPath], with: .automatic)


// MARK: - Segues

override func prepare(for segue: UIStoryboardSegue, sender: Any?)
if segue.identifier == "showDetail"
if let indexPath = tableView.indexPathForSelectedRow
let object = objects[indexPath.row] as! NSDate
let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
controller.detailItem = object
controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
controller.navigationItem.leftItemsSupplementBackButton = true




// MARK: - Table View

override func numberOfSections(in tableView: UITableView) -> Int
return 1


override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return objects.count


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

let object = objects[indexPath.row] as! NSDate
cell.textLabel!.text = object.description
return cell


override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool
// Return false if you do not want the specified item to be editable.
return true


override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath)
if editingStyle == .delete
objects.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
else if editingStyle == .insert
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.










ios swift






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 13 '18 at 19:50







Richard Leinfellner

















asked Nov 13 '18 at 9:31









Richard LeinfellnerRichard Leinfellner

32




32












  • Where do you call the UpdateDetail method in the non-timer version? Is it called on UI thread?

    – Peter Pajchl
    Nov 13 '18 at 11:11











  • Yes, I added DispatchQueue.main.async self.detailViewController?.UpdateDetail()

    – Richard Leinfellner
    Nov 13 '18 at 18:32












  • Hello there and welcome on board. Do you have a link to the project?

    – Lausbert
    Nov 13 '18 at 20:08











  • github.com/RLTeachGit/DetailViewIssue.git I have uploaded it here

    – Richard Leinfellner
    Nov 13 '18 at 20:37












  • Unrelated but begin-/endUpdates() has no effect at all when reloading rows or data.

    – vadian
    Nov 14 '18 at 9:53


















  • Where do you call the UpdateDetail method in the non-timer version? Is it called on UI thread?

    – Peter Pajchl
    Nov 13 '18 at 11:11











  • Yes, I added DispatchQueue.main.async self.detailViewController?.UpdateDetail()

    – Richard Leinfellner
    Nov 13 '18 at 18:32












  • Hello there and welcome on board. Do you have a link to the project?

    – Lausbert
    Nov 13 '18 at 20:08











  • github.com/RLTeachGit/DetailViewIssue.git I have uploaded it here

    – Richard Leinfellner
    Nov 13 '18 at 20:37












  • Unrelated but begin-/endUpdates() has no effect at all when reloading rows or data.

    – vadian
    Nov 14 '18 at 9:53

















Where do you call the UpdateDetail method in the non-timer version? Is it called on UI thread?

– Peter Pajchl
Nov 13 '18 at 11:11





Where do you call the UpdateDetail method in the non-timer version? Is it called on UI thread?

– Peter Pajchl
Nov 13 '18 at 11:11













Yes, I added DispatchQueue.main.async self.detailViewController?.UpdateDetail()

– Richard Leinfellner
Nov 13 '18 at 18:32






Yes, I added DispatchQueue.main.async self.detailViewController?.UpdateDetail()

– Richard Leinfellner
Nov 13 '18 at 18:32














Hello there and welcome on board. Do you have a link to the project?

– Lausbert
Nov 13 '18 at 20:08





Hello there and welcome on board. Do you have a link to the project?

– Lausbert
Nov 13 '18 at 20:08













github.com/RLTeachGit/DetailViewIssue.git I have uploaded it here

– Richard Leinfellner
Nov 13 '18 at 20:37






github.com/RLTeachGit/DetailViewIssue.git I have uploaded it here

– Richard Leinfellner
Nov 13 '18 at 20:37














Unrelated but begin-/endUpdates() has no effect at all when reloading rows or data.

– vadian
Nov 14 '18 at 9:53






Unrelated but begin-/endUpdates() has no effect at all when reloading rows or data.

– vadian
Nov 14 '18 at 9:53













2 Answers
2






active

oldest

votes


















0














My answer is based on the provided Git repository.



In MasterViewController - you are calling self.detailViewController?.configureView() but you never assign the detail controller and because it's nil it fails to call the configureView function. You can do that in prepare(for segue: UIStoryboardSegue, sender: Any?) by setting self.detailViewController = controller



This won't still help you with the update of the label value.



The reason fo that is because in @objc func doTimer() { you are always setting (overriding) a new Date object into your array (what you probably aimed for is to update value for same reference). Because of this, the reference you assigned to detailViewController is different and you never update the detailItem in your timer. Hence calling the configureView won't make any change as the value remained the same.






share|improve this answer























  • Many thanks for taking a look at this I thought this too, however after the first seque the value is set and the configureview() is called, I checked this by setting a BP and tracing into the call. The trace confirms it calls configureview() however once inside @IBOutlet weak var detailDescriptionLabel: UILabel! is nil I also added code to resync detailItem just before the call and it still does not update. Many thanks for all your help, but I think its taken enough time and I don't have to do it this way, it was just my first attempt at Swift so needed a sanity check

    – Richard Leinfellner
    Nov 14 '18 at 18:36











  • Here is your project with my correction - perhaps it might explain some things transfernow.net/25fc20z8ac06

    – Peter Pajchl
    Nov 14 '18 at 18:41











  • OK, that works A-OK. Thank you! So is this the magic line? self.detailViewController?.detailItem = self.objects[0]

    – Richard Leinfellner
    Nov 14 '18 at 19:02












  • That was so incredibly helpful, thank you for taking the time. I have accepted your answer, but don't have the rep your to to more good.

    – Richard Leinfellner
    Nov 14 '18 at 19:07











  • BTW. I appears that underlying issue is that detailViewController which set up in viewDidLoad() is not the same instance as the one in the seque let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController, so setting anything using detailViewController does not impact the actual currently displayed detailview. When I use the one set in the seque it works just fine, and your example led me straight to this conclusion.

    – Richard Leinfellner
    Nov 14 '18 at 19:35



















-2














It's happening because your detailDescription label is weak "weak var detailDescription". and each time you write this code



guard let label = detailDescription else 
return; //Label not linked

label.text = "New Data"


you create a new object and assign value to that object. So the original value for detailDescription label object doesn't change. Try using the same detailDescription object everytime when you change its value.






share|improve this answer























  • UILabel is a class which is passed by reference and therefore the statement above only assigns the reference to label (as long as unwrapping succeeds); hence your statement is invalid

    – Peter Pajchl
    Nov 13 '18 at 13:53











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53277821%2fswift-ios-issues-updating-label-in-detailview-from-masterview%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














My answer is based on the provided Git repository.



In MasterViewController - you are calling self.detailViewController?.configureView() but you never assign the detail controller and because it's nil it fails to call the configureView function. You can do that in prepare(for segue: UIStoryboardSegue, sender: Any?) by setting self.detailViewController = controller



This won't still help you with the update of the label value.



The reason fo that is because in @objc func doTimer() { you are always setting (overriding) a new Date object into your array (what you probably aimed for is to update value for same reference). Because of this, the reference you assigned to detailViewController is different and you never update the detailItem in your timer. Hence calling the configureView won't make any change as the value remained the same.






share|improve this answer























  • Many thanks for taking a look at this I thought this too, however after the first seque the value is set and the configureview() is called, I checked this by setting a BP and tracing into the call. The trace confirms it calls configureview() however once inside @IBOutlet weak var detailDescriptionLabel: UILabel! is nil I also added code to resync detailItem just before the call and it still does not update. Many thanks for all your help, but I think its taken enough time and I don't have to do it this way, it was just my first attempt at Swift so needed a sanity check

    – Richard Leinfellner
    Nov 14 '18 at 18:36











  • Here is your project with my correction - perhaps it might explain some things transfernow.net/25fc20z8ac06

    – Peter Pajchl
    Nov 14 '18 at 18:41











  • OK, that works A-OK. Thank you! So is this the magic line? self.detailViewController?.detailItem = self.objects[0]

    – Richard Leinfellner
    Nov 14 '18 at 19:02












  • That was so incredibly helpful, thank you for taking the time. I have accepted your answer, but don't have the rep your to to more good.

    – Richard Leinfellner
    Nov 14 '18 at 19:07











  • BTW. I appears that underlying issue is that detailViewController which set up in viewDidLoad() is not the same instance as the one in the seque let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController, so setting anything using detailViewController does not impact the actual currently displayed detailview. When I use the one set in the seque it works just fine, and your example led me straight to this conclusion.

    – Richard Leinfellner
    Nov 14 '18 at 19:35
















0














My answer is based on the provided Git repository.



In MasterViewController - you are calling self.detailViewController?.configureView() but you never assign the detail controller and because it's nil it fails to call the configureView function. You can do that in prepare(for segue: UIStoryboardSegue, sender: Any?) by setting self.detailViewController = controller



This won't still help you with the update of the label value.



The reason fo that is because in @objc func doTimer() { you are always setting (overriding) a new Date object into your array (what you probably aimed for is to update value for same reference). Because of this, the reference you assigned to detailViewController is different and you never update the detailItem in your timer. Hence calling the configureView won't make any change as the value remained the same.






share|improve this answer























  • Many thanks for taking a look at this I thought this too, however after the first seque the value is set and the configureview() is called, I checked this by setting a BP and tracing into the call. The trace confirms it calls configureview() however once inside @IBOutlet weak var detailDescriptionLabel: UILabel! is nil I also added code to resync detailItem just before the call and it still does not update. Many thanks for all your help, but I think its taken enough time and I don't have to do it this way, it was just my first attempt at Swift so needed a sanity check

    – Richard Leinfellner
    Nov 14 '18 at 18:36











  • Here is your project with my correction - perhaps it might explain some things transfernow.net/25fc20z8ac06

    – Peter Pajchl
    Nov 14 '18 at 18:41











  • OK, that works A-OK. Thank you! So is this the magic line? self.detailViewController?.detailItem = self.objects[0]

    – Richard Leinfellner
    Nov 14 '18 at 19:02












  • That was so incredibly helpful, thank you for taking the time. I have accepted your answer, but don't have the rep your to to more good.

    – Richard Leinfellner
    Nov 14 '18 at 19:07











  • BTW. I appears that underlying issue is that detailViewController which set up in viewDidLoad() is not the same instance as the one in the seque let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController, so setting anything using detailViewController does not impact the actual currently displayed detailview. When I use the one set in the seque it works just fine, and your example led me straight to this conclusion.

    – Richard Leinfellner
    Nov 14 '18 at 19:35














0












0








0







My answer is based on the provided Git repository.



In MasterViewController - you are calling self.detailViewController?.configureView() but you never assign the detail controller and because it's nil it fails to call the configureView function. You can do that in prepare(for segue: UIStoryboardSegue, sender: Any?) by setting self.detailViewController = controller



This won't still help you with the update of the label value.



The reason fo that is because in @objc func doTimer() { you are always setting (overriding) a new Date object into your array (what you probably aimed for is to update value for same reference). Because of this, the reference you assigned to detailViewController is different and you never update the detailItem in your timer. Hence calling the configureView won't make any change as the value remained the same.






share|improve this answer













My answer is based on the provided Git repository.



In MasterViewController - you are calling self.detailViewController?.configureView() but you never assign the detail controller and because it's nil it fails to call the configureView function. You can do that in prepare(for segue: UIStoryboardSegue, sender: Any?) by setting self.detailViewController = controller



This won't still help you with the update of the label value.



The reason fo that is because in @objc func doTimer() { you are always setting (overriding) a new Date object into your array (what you probably aimed for is to update value for same reference). Because of this, the reference you assigned to detailViewController is different and you never update the detailItem in your timer. Hence calling the configureView won't make any change as the value remained the same.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 14 '18 at 9:50









Peter PajchlPeter Pajchl

2,2321624




2,2321624












  • Many thanks for taking a look at this I thought this too, however after the first seque the value is set and the configureview() is called, I checked this by setting a BP and tracing into the call. The trace confirms it calls configureview() however once inside @IBOutlet weak var detailDescriptionLabel: UILabel! is nil I also added code to resync detailItem just before the call and it still does not update. Many thanks for all your help, but I think its taken enough time and I don't have to do it this way, it was just my first attempt at Swift so needed a sanity check

    – Richard Leinfellner
    Nov 14 '18 at 18:36











  • Here is your project with my correction - perhaps it might explain some things transfernow.net/25fc20z8ac06

    – Peter Pajchl
    Nov 14 '18 at 18:41











  • OK, that works A-OK. Thank you! So is this the magic line? self.detailViewController?.detailItem = self.objects[0]

    – Richard Leinfellner
    Nov 14 '18 at 19:02












  • That was so incredibly helpful, thank you for taking the time. I have accepted your answer, but don't have the rep your to to more good.

    – Richard Leinfellner
    Nov 14 '18 at 19:07











  • BTW. I appears that underlying issue is that detailViewController which set up in viewDidLoad() is not the same instance as the one in the seque let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController, so setting anything using detailViewController does not impact the actual currently displayed detailview. When I use the one set in the seque it works just fine, and your example led me straight to this conclusion.

    – Richard Leinfellner
    Nov 14 '18 at 19:35


















  • Many thanks for taking a look at this I thought this too, however after the first seque the value is set and the configureview() is called, I checked this by setting a BP and tracing into the call. The trace confirms it calls configureview() however once inside @IBOutlet weak var detailDescriptionLabel: UILabel! is nil I also added code to resync detailItem just before the call and it still does not update. Many thanks for all your help, but I think its taken enough time and I don't have to do it this way, it was just my first attempt at Swift so needed a sanity check

    – Richard Leinfellner
    Nov 14 '18 at 18:36











  • Here is your project with my correction - perhaps it might explain some things transfernow.net/25fc20z8ac06

    – Peter Pajchl
    Nov 14 '18 at 18:41











  • OK, that works A-OK. Thank you! So is this the magic line? self.detailViewController?.detailItem = self.objects[0]

    – Richard Leinfellner
    Nov 14 '18 at 19:02












  • That was so incredibly helpful, thank you for taking the time. I have accepted your answer, but don't have the rep your to to more good.

    – Richard Leinfellner
    Nov 14 '18 at 19:07











  • BTW. I appears that underlying issue is that detailViewController which set up in viewDidLoad() is not the same instance as the one in the seque let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController, so setting anything using detailViewController does not impact the actual currently displayed detailview. When I use the one set in the seque it works just fine, and your example led me straight to this conclusion.

    – Richard Leinfellner
    Nov 14 '18 at 19:35

















Many thanks for taking a look at this I thought this too, however after the first seque the value is set and the configureview() is called, I checked this by setting a BP and tracing into the call. The trace confirms it calls configureview() however once inside @IBOutlet weak var detailDescriptionLabel: UILabel! is nil I also added code to resync detailItem just before the call and it still does not update. Many thanks for all your help, but I think its taken enough time and I don't have to do it this way, it was just my first attempt at Swift so needed a sanity check

– Richard Leinfellner
Nov 14 '18 at 18:36





Many thanks for taking a look at this I thought this too, however after the first seque the value is set and the configureview() is called, I checked this by setting a BP and tracing into the call. The trace confirms it calls configureview() however once inside @IBOutlet weak var detailDescriptionLabel: UILabel! is nil I also added code to resync detailItem just before the call and it still does not update. Many thanks for all your help, but I think its taken enough time and I don't have to do it this way, it was just my first attempt at Swift so needed a sanity check

– Richard Leinfellner
Nov 14 '18 at 18:36













Here is your project with my correction - perhaps it might explain some things transfernow.net/25fc20z8ac06

– Peter Pajchl
Nov 14 '18 at 18:41





Here is your project with my correction - perhaps it might explain some things transfernow.net/25fc20z8ac06

– Peter Pajchl
Nov 14 '18 at 18:41













OK, that works A-OK. Thank you! So is this the magic line? self.detailViewController?.detailItem = self.objects[0]

– Richard Leinfellner
Nov 14 '18 at 19:02






OK, that works A-OK. Thank you! So is this the magic line? self.detailViewController?.detailItem = self.objects[0]

– Richard Leinfellner
Nov 14 '18 at 19:02














That was so incredibly helpful, thank you for taking the time. I have accepted your answer, but don't have the rep your to to more good.

– Richard Leinfellner
Nov 14 '18 at 19:07





That was so incredibly helpful, thank you for taking the time. I have accepted your answer, but don't have the rep your to to more good.

– Richard Leinfellner
Nov 14 '18 at 19:07













BTW. I appears that underlying issue is that detailViewController which set up in viewDidLoad() is not the same instance as the one in the seque let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController, so setting anything using detailViewController does not impact the actual currently displayed detailview. When I use the one set in the seque it works just fine, and your example led me straight to this conclusion.

– Richard Leinfellner
Nov 14 '18 at 19:35






BTW. I appears that underlying issue is that detailViewController which set up in viewDidLoad() is not the same instance as the one in the seque let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController, so setting anything using detailViewController does not impact the actual currently displayed detailview. When I use the one set in the seque it works just fine, and your example led me straight to this conclusion.

– Richard Leinfellner
Nov 14 '18 at 19:35














-2














It's happening because your detailDescription label is weak "weak var detailDescription". and each time you write this code



guard let label = detailDescription else 
return; //Label not linked

label.text = "New Data"


you create a new object and assign value to that object. So the original value for detailDescription label object doesn't change. Try using the same detailDescription object everytime when you change its value.






share|improve this answer























  • UILabel is a class which is passed by reference and therefore the statement above only assigns the reference to label (as long as unwrapping succeeds); hence your statement is invalid

    – Peter Pajchl
    Nov 13 '18 at 13:53
















-2














It's happening because your detailDescription label is weak "weak var detailDescription". and each time you write this code



guard let label = detailDescription else 
return; //Label not linked

label.text = "New Data"


you create a new object and assign value to that object. So the original value for detailDescription label object doesn't change. Try using the same detailDescription object everytime when you change its value.






share|improve this answer























  • UILabel is a class which is passed by reference and therefore the statement above only assigns the reference to label (as long as unwrapping succeeds); hence your statement is invalid

    – Peter Pajchl
    Nov 13 '18 at 13:53














-2












-2








-2







It's happening because your detailDescription label is weak "weak var detailDescription". and each time you write this code



guard let label = detailDescription else 
return; //Label not linked

label.text = "New Data"


you create a new object and assign value to that object. So the original value for detailDescription label object doesn't change. Try using the same detailDescription object everytime when you change its value.






share|improve this answer













It's happening because your detailDescription label is weak "weak var detailDescription". and each time you write this code



guard let label = detailDescription else 
return; //Label not linked

label.text = "New Data"


you create a new object and assign value to that object. So the original value for detailDescription label object doesn't change. Try using the same detailDescription object everytime when you change its value.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 13 '18 at 13:20









SAIFSAIF

768




768












  • UILabel is a class which is passed by reference and therefore the statement above only assigns the reference to label (as long as unwrapping succeeds); hence your statement is invalid

    – Peter Pajchl
    Nov 13 '18 at 13:53


















  • UILabel is a class which is passed by reference and therefore the statement above only assigns the reference to label (as long as unwrapping succeeds); hence your statement is invalid

    – Peter Pajchl
    Nov 13 '18 at 13:53

















UILabel is a class which is passed by reference and therefore the statement above only assigns the reference to label (as long as unwrapping succeeds); hence your statement is invalid

– Peter Pajchl
Nov 13 '18 at 13:53






UILabel is a class which is passed by reference and therefore the statement above only assigns the reference to label (as long as unwrapping succeeds); hence your statement is invalid

– Peter Pajchl
Nov 13 '18 at 13:53


















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53277821%2fswift-ios-issues-updating-label-in-detailview-from-masterview%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

How to how show current date and time by default on contact form 7 in WordPress without taking input from user in datetimepicker

Syphilis

Darth Vader #20