Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
395 views
in Technique[技术] by (71.8m points)

ios - Custom init of UIViewController from storyboard

I tried finding some relevant questions but couldn't get anything, hope someone can help.

I set up some UIViewController's on a storyboard. I then want to load one of the view controllers in code and push it onto the navigation stack. I figure out the right way to do this is to use

instantiateViewControllerWithIdentifier

This calls init(coder: NSCoder) and all is well, my program works, but I want to be able to have a custom initializer that sets up some variables for my view controller. Consider the following:

class A : UIViewController {   

  let i : Int

  required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    // property self.i not initialized at super.init call   
  }

}

I obviously get an error since i needs to be specified at time of object creation. Any solutions to this? I am not interested in declaring i as var and configuring it later as that defeats the point and I no longer have a compiler guarantee that i is immutable.

Clarification edit

Suppose I have a currently loaded ViewController that has some variable i. This value is variable and can change. Now suppose from this ViewController I want to present another one, and initialize it with i.

class ViewController: UIViewController {

   var i : Int

   // ... other things

  // in response to some button tap...
  @IBAction func tappedButton(sender: AnyObject) {
    let st = UIStoryboard(name: "Main", bundle: nil)
    let vc = st.instantiateViewControllerWithIdentifier("AControllerID") as! A
    // How do I initialize A with i ?
    self.presentViewController(vc, animated: true, completion: nil)
  }

}

I don't seem to be able to do this and keep i immutable by using let instead of var.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

A simplification of my prior answer which is quick and avoids alternative hacky fixes:

Here is a detail view controller you may want to instantiate from storyboard with an objectID set:

import UIKit

class DetailViewController: UIViewController {

    var objectID : Int!

    internal static func instantiate(with objectID: Int) -> DetailViewController {

        let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "DetailViewController") as DetailViewController
        vc.objectID = objectID
        return vc
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        if((objectID) != nil){
            print("Here is my objectID: (objectID)")
        }
    }
}

Here is how you would use it to push onto a navigation controller with objectID set to 1:

self.navigationController.pushViewController(DetailViewController.instantiate(1), animated: true)

Added a blog post: https://theswiftcook.wordpress.com/2017/02/17/how-to-initialize-a-storyboard-viewcontroller-with-data-without-segues-swift-3-0git/

Link to example on GitHub: https://github.com/hammadzz/Instantiate-ViewController-From-Storyboard-With-Data


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...