Swift IOS Issues updating Label in DetailView from MasterView
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
add a comment |
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
Where do you call theUpdateDetail
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 butbegin-/endUpdates()
has no effect at all whenreload
ing rows or data.
– vadian
Nov 14 '18 at 9:53
add a comment |
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
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
ios swift
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 theUpdateDetail
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 butbegin-/endUpdates()
has no effect at all whenreload
ing rows or data.
– vadian
Nov 14 '18 at 9:53
add a comment |
Where do you call theUpdateDetail
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 butbegin-/endUpdates()
has no effect at all whenreload
ing 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 reload
ing rows or data.– vadian
Nov 14 '18 at 9:53
Unrelated but
begin-/endUpdates()
has no effect at all when reload
ing rows or data.– vadian
Nov 14 '18 at 9:53
add a comment |
2 Answers
2
active
oldest
votes
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.
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
add a comment |
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.
UILabel
is aclass
which is passed by reference and therefore the statement above only assigns the reference tolabel
(as long as unwrapping succeeds); hence your statement is invalid
– Peter Pajchl
Nov 13 '18 at 13:53
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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
add a comment |
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.
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
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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.
UILabel
is aclass
which is passed by reference and therefore the statement above only assigns the reference tolabel
(as long as unwrapping succeeds); hence your statement is invalid
– Peter Pajchl
Nov 13 '18 at 13:53
add a comment |
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.
UILabel
is aclass
which is passed by reference and therefore the statement above only assigns the reference tolabel
(as long as unwrapping succeeds); hence your statement is invalid
– Peter Pajchl
Nov 13 '18 at 13:53
add a comment |
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.
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.
answered Nov 13 '18 at 13:20
SAIFSAIF
768
768
UILabel
is aclass
which is passed by reference and therefore the statement above only assigns the reference tolabel
(as long as unwrapping succeeds); hence your statement is invalid
– Peter Pajchl
Nov 13 '18 at 13:53
add a comment |
UILabel
is aclass
which is passed by reference and therefore the statement above only assigns the reference tolabel
(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
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 whenreload
ing rows or data.– vadian
Nov 14 '18 at 9:53