简体   繁体   中英

Swift - can't call public function from child view controller? ViewController has no member error?

Alright, so in the past I have been able to create new child view controllers like this and then be able to call functions within them easily:

let v : ResultsViewController = ResultsViewController (nibName: "ResultsViewController", bundle: nil)
self.addChildViewController(v)
        self.view.addSubview(v.view)
        v.didMoveToParentViewController(self)

        v.view.frame = self.view.bounds

v.doSomething(self)

Where doSomething was a public func in the Results VC class with any object as sender.

I am attempting to do the exact same thing while creating the VC slightly different but am getting the error 在此处输入图片说明

With this:

at class level I have var skip = UIViewController()

Then in a function:

skip = Results2ViewController (nibName: "Results2ViewController", bundle: nil)
        self.addChildViewController(skip)
        self.view.addSubview(skip.view)
        skip.didMoveToParentViewController(self)

        skip.view.frame = self.view.bounds
        self.view.bringSubviewToFront(skip.view)
        //make sure accept is there
        self.view.bringSubviewToFront(circleView)

        skip.definesPresentationContext = false;
        skip.view.frame.origin.x -= self.view.bounds.width
skip.setIdeaLabels(self) //ERROR

Where in the Results 2 class I have like always

public func setIdeaLabels(sender: AnyObject)

I have to write it this way and not just declaring skip as let skip = Results2ViewController (nibName: "Results2ViewController", bundle: nil) because I reuse this skip variable elsewhere and the variable would go out of scope.

Why can't I call a function in my child view controller? Why doesn't it have member?

When you declare var skip = UIViewController() , then skip is implicitly typed as UIViewController . You can't change the type of a variable after it is declared - Results2ViewController is a UIViewController , so it "fits" in skip . But the compiler still sees it as being a UIViewController so it doesn't have the methods of a Results2ViewController .

You can set the instance variable to have the correct type, you can cast it when you need to call that method or you can use a local reference of the correct type to call that method.

1) Replace var skip = UIViewController() with var skip : Results2ViewController? Notice how I made skip optional and did not initialize it to anything. You could also use var skip = Results2ViewController (nibName: "Results2ViewController", bundle: nil) but I assume there is some reason you aren't doing that in the first place.

2) Cast skip before calling setIdeaLabels .

skip = Results2ViewController (nibName: "Results2ViewController", bundle: nil)
var results = skip as! Results2ViewController;
results.setIdeaLabels(self);

3) Initialize it locally, then set it to skip when you're done.

let results = Results2ViewController (nibName: "Results2ViewController", bundle: nil)
results.setIdeaLabels(self);
skip = results;

Options 2 and 3 are pretty similar. I'd go with 3 purely because I'm not a fan of using extra casts. I like 1 but it leaves you with a lot of potential for unwrapping an optional all over the place.

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