Displaying a UIAlertController in GameScene (SpriteKit/Swift)

后端 未结 3 936
青春惊慌失措
青春惊慌失措 2021-01-15 00:39

The simple way to display a UIAlertView, in swift is:

let alert = UIAlertView()
alert.title = \"Alert!\"
alert.message = \"A wise message\"
alert.addButtonWi         


        
3条回答
  •  难免孤独
    2021-01-15 01:21

    There are many ways to handle this situation, I do not recommend Jozemite Apps answer, because this will cause problems on apps with more than 1 view controller.(you want to present the alert on the current view controller, not the root)

    My preferred way of doing it is through delegation. What needs to be done is create a protocol to handle messaging:

    import Foundation
    protocol ViewControllerDelegate
    {
        func sendMessage(message:String);
    }
    

    In your view controller:

    class ViewController : UIViewController, ViewControllerDelegate
    {
        ...
        func sendMessage(message:String)
        {
           //do alert view code here
        }
    
        //in the view controllers view did load event
        func viewDidLoad()
        {
            var view = self.view as! GameSceneView
            view.delegate = self
        }
    

    In your view code:

      var delegate : ViewControllerDelegate
    

    Finally in game scene where you want to present:

    self.view.delegate?.sendMessage(message)
    

    This way allows limited access to the VC, and can be modified with more options when needed.

    Another way is to set up a notification system, and use NSNotificationCenter to pass a message from the scene to the current VC and have it send a message;

    in ViewController

    func viewDidLoad()
    {
      NSNotificationCenter.defaultCenter().addObserver(self,selector:"AlertMessage:",name:"AlertMessage",object:nil);
    
    }
    
    func AlertMessage(notification:NSNotification)
    {
        if(let userInfo = notification.userInfo)
        {
          let message = userInfo["message"]
          ....//do alert view call here
        }
    }
    

    In Game scene code:

    ...at the spot you want to send a message
    let userInfo = ["message":message];
    NSNotificationCenter.defaultCenter.postNotificationNamed("AlertMessage",object:nil,userInfo:userInfo)
    

    Another approach is to save the view controller pointer to game scene view:

    //in Game Scene View code
    var viewController : UIViewController; 
    
    //in the view controllers view did load event
    func viewDidLoad()
    {
        var view = self.view as! GameSceneView
        view.viewController = self
    }
    
    //finally in game scene where you want to present
    let myAlert: UIAlertController = UIAlertController(title: "Alert!", message: "Oh! Fancy", preferredStyle: .Alert)
    myAlert.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
    self.view.viewController.presentViewController(myAlert, animated: true, completion: nil)
    

    Yet another way is to make your view controller global.

    In view controller code: private var _instance : UIViewController

    class ViewController : UIViewController
    {
        class var instance
        {
            get
            {
                return _instance;
            }
        }
    
        func viewDidLoad()
        {
           _instance = self;
        }
    }
    

    Then just call

    ViewController.instance!.  
    

    whenever you need access to your view controller.

    Each of these methods have there strengths and weaknesses, so choose whatever way works best for you.

提交回复
热议问题