简体   繁体   中英

SWIFT: how to use performSegueWithIdentifier from different class

I'm trying to make my App to automatically go back to the main menu after 2 minutes of inactivity. So far I have both parts working, but not together..

The App starts a counter if there's no touch input:

see user4806509's anwer on Detecting when an app is active or inactive through touches in Swift

And from my main viewcontroller I can control the segue I need with code:

func goToMenu()
{
    performSegueWithIdentifier("backToMenu", sender: self)
}

I've implemented the code from Rob's answer on How to call performSegueWithIdentifier from xib?

So I've created the following class and protocol:

protocol CustomViewDelegate: class {
    func goToMenu()
}
class CustomView: UIView
{
weak var delegate: CustomViewDelegate?
    func go() {
        delegate?.goToMenu()
    }
}

The Function go() gets (successfully) called when the timer runs out. But the delegate?.goToMenu() doesn't work. If I change it to: delegate!.goToMenu(), the App crashes with:

fatal error: unexpectedly found nil while unwrapping an Optional value

My main viewcontroller is a CustomViewDelegate and the viewDidLoad contains:

let myCustomView = NSBundle.mainBundle().loadNibNamed("customView", owner: self, options: nil)[0] as! CustomView
myCustomView.delegate = self

I have the correct xib file, and that part is working.

I can't seem to find the solution to this seemingly easy problem, does anyone have a fix? Or better yet, a more elegant solution to my problem?

Thank you!

edit: SOLUTION:

I've removed all my old code and implemented the NSNotification method:

In the UIApplication:

let CallForUnwindSegue = "nl.timfi.unwind"

func delayedAction()
{
    NSNotificationCenter.defaultCenter().postNotificationName(CallForUnwindSegue, object: nil)
}

In the main ViewController:

let CallForUnwindSegue = "nl.timfi.unwind"
func goToMenu(notification: NSNotification) 
{
    performSegueWithIdentifier("backToMenu", sender: self)
}
deinit 
{
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

In the viewDidLoad: NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(PeriodViewController.goToMenu), name:CallForUnwindSegue , object: nil)

I believe that your issue is that because your delegate is declared as a weak var, your delegate is getting disposed while you wait for the timer to complete, thus the reference to the optional is lost (and returns nil when you force unwrap it).

try removing the weak keyword from your CustomView class.

Another solution would be to use the notification center to notify your view to call for the segue.

Something along the lines of what I proposed here

I hope this helps.

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