Yevgen
Yevgen

Reputation: 101

Can't pass data via segue

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

Answers (1)

ivanmoskalev
ivanmoskalev

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

Related Questions