Search code examples
iosxcodexcode7uialertcontrollerswift-playground

Swift playground: get ViewController to call presentViewController


I would like to play with UIAlertController in Playground. Is it possible to get the ViewController from XCPlaygroundPage - to be able to call presentViewController?


Solution

  • Yes, you can certainly get a view controller, but because there's no "attached" view controller you'll end up seeing a warning that looks like this:

    Presenting view controllers on detached view controllers is discouraged

    And in my case, the alert controller flash on screen super briefly and then disappeared. Perhaps you could improve upon this somewhat?

    Anyways, here is how I created the view controllers in the playground:

    import UIKit
    import XCPlayground
    
    class RootViewController: UIViewController {
        override func viewDidLoad() {
            super.viewDidLoad()
            self.view.frame = CGRect(x: 0, y: 0, width: 350, height: 420)
            self.view.backgroundColor = UIColor.redColor()
        }
    }
    
    class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
        var tableView: UITableView!
        let items = ["Hello 1", "Hello 2", "Hello 3"]
        var alertController : UIAlertController? {
            didSet {
                if alertController == nil {
                    print("alertController set to nil")
                } else {
                    print("alertController set to \(alertController)")
                }
            }
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
            self.view.frame = CGRect(x: 0, y: 0, width: 320, height: 480)
            self.tableView = UITableView(frame:self.view.frame)
            self.tableView!.dataSource = self
            self.tableView!.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
            self.view.addSubview(self.tableView)
    
        }
        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
            return self.items.count;
        }
    
        func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
            let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell
            cell.textLabel?.text = "\(self.items[indexPath.row])"
            return cell
        }
    
        override func viewDidAppear(animated: Bool) {
            alertController = UIAlertController.init(title: "My Title", message: "Testing in Playground", preferredStyle: .Alert)
    
            let okAction = UIAlertAction(title: "Ok", style: .Default) { (_) -> Void in
                // Some action here
                print("hit okay button")
            }
    
            alertController!.addAction(okAction)
    
            ctrl.presentViewController(alertController!, animated: false, completion: {
                print("done presenting")
            })
        }
    }
    
    var ctrl = ViewController()
    var rootVC = RootViewController()
    rootVC.addChildViewController(ctrl)
    rootVC.view.addSubview(ctrl.view)
    XCPlaygroundPage.currentPage.liveView = rootVC.view
    

    And what I'm doing here is I create a "root view controller", add a child view controller with a table (in an attempt to get some view controller "attached" to something else) and then I tried to present an alert controller on that.