Reputation: 101
I make app with news feed which has to open on other ViewController. But can't pass data via segue.
Viewcontroller with newsfeed
class SecondViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var titlenews = ""
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "newsfeedCell", for: indexPath) as! NewsFeedCell
cell.newsfeed_title.text = self.news?[indexPath.item].headline
cell.newsfeed_topic.text = self.news?[indexPath.item].topic
cell.newsfeed_time.text = timetime(from: (self.news?[indexPath.item].time)!)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("tableview")
let vc = storyboard?.instantiateViewController(withIdentifier: "newsBody") as? NewsBody
vc?.labeltext = (self.news?[indexPath.item].headline)!
print((self.news?[indexPath.item].headline)!)
self.navigationController?.pushViewController(vc!, animated: true)
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.news!.count
} //number of rows
@IBOutlet weak var tableview: UITableView!
var news: [Newsfeed]? = []
override func viewDidLoad() {
super.viewDidLoad()
getJSON()
}
func getJSON(){
///Here all do right
}
}
Viewcontroller which has to receive data from news feed
class NewsBody: UIViewController {
@IBOutlet weak var testLabel: UILabel!
var labeltext = ""
override func viewDidLoad() {
super.viewDidLoad()
print(labeltext)
testLabel.text = labeltext
}
}
print(labeltext)
shows that NewsBody
receive empty value or nothing.
But print((self.news?[indexPath.item].headline)!)
inside of SecondViewController
shows that I try to push proper value.
What I do incorrect between this actions? What wrong with segue and pass of data?
Upvotes: 0
Views: 75
Reputation: 2064
It seems that instantiateViewController(withIdentifier: "newsBody")
triggers view load under the hood. It should not (in theory) but it might do just that in your case.
This means that viewDidLoad()
will be called before the vc?.labeltext = (self.news?[indexPath.item].headline)!
is executed.
I'd recommend you to do the following.
class NewsBody: UIViewController {
@IBOutlet weak var testLabel: UILabel!
var labeltext: String? {
didSet { updateUI() }
}
override func viewDidLoad() {
super.viewDidLoad()
updateUI()
}
private func updateUI() {
testLabel.text = labeltext
}
}
This way if you set the labeltext
property after the view is loaded, it will still trigger the UI update. And if you set the labeltext
property before the view is loaded, as soon as viewDidLoad()
is called.
BTW, you are not using segues here. But even if you do, you can easily use the same method as I proposed, because it allows you to stop thinking about whether property updates will update the UI.
Also please note that I made the property optional. It will allow you to avoid force casts and just do
vc?.labeltext = self.news?[indexPath.item].headline
UILabel.text
is also an optional String
property, so they will play well together.
Upvotes: 5