简体   繁体   中英

How to get global pointer to view controller in swift

I'm building an app using swift. In my app, I need to present a UIPopoverPresentationController, and I also need to acces the content controller from that popover from other methods in my normal view controller.

To do this, I would normally in objective C just create a global pointer to my view controller, which would allow me to access it from any method.

This is how I would do it in Swift:

class Categories: UITableViewController, UIPopoverPresentationControllerDelegate {

let storyBoard = UIStoryboard(name: "Main", bundle:nil)
var newCategory = self.storyBoard.instantiateViewControllerWithIdentifier("NewCategory") as NewCategory

//rest of my code

When I do this, Xcode gives me the error:

Categories.type does not have a member named 'storyBoard'

Can anybody tell me what I'm doing wrong and how I need to modify my code to create a legit global pointer to my view controller? Any help would be highly appreciated!

You should use @lazy attribute for this. Bellow is general receipt:

class MyClass {
    let compileTimeProperty = "compileTimePropert"

    @lazy var runTimeProperty:String = {
        return self.compileTimeProperty
    }()
}

And here is how your code should be adjusted:

class Categories: UITableViewController, UIPopoverPresentationControllerDelegate {

    let storyBoard = UIStoryboard(name: "Main", bundle:nil)

    @lazy var newCategory: NewCategory = {
        return self.storyBoard.instantiateViewControllerWithIdentifier("NewCategory") as NewCategory
    }()

    //rest of your code
}

You are putting that var declaration outside of any code (ie at the top level of the Categories class, not inside any function). You cannot refer to self in the default value of a variable declaration outside of a func unless you also declare that variable as @lazy .

Thus in general:

class MyClass {
    let howdy = "howdy"
    var hello = self.howdy // illegal

    func f() {
        var hello = self.howdy // legal
    }
}

Your code is only giving default values for storyBoard and newCategory , but Swift does not guarantee that the default property values will be initialized in any particular order. Consequently, it's illegal to reference another property in the default value for one. Move the code for setting those values into an init and it should work fine:

class Categories: UITableViewController, UIPopoverPresentationControllerDelegate {

let storyBoard: UIStoryboard
var newCategory: NewCategory

init {
    storyBoard = UIStoryboard(name: "Main", bundle:nil)
    newCategory = self.storyBoard.instantiateViewControllerWithIdentifier("NewCategory") as NewCategory
}

//rest of code

To be clear on terminology: declaring variables at the top level of class like this doesn't make them "global variables", it makes the properties of the class. (Global variables are declared outside the scope of any class/struct/function.) Also, the rules for properties are different from other variables, in that you do NOT need to assign a value when you declare them (and if you do, it's only treated as a default value) -- the real requirement is that you must either provide a default value, OR assign a value in the initializer.

But for this particular case, Keenle's @lazy solution is the more appropriate choice.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM