While doing some work on more material for the site in Swift playgrounds, I ran into a serious bug in the Swift Playgrounds for iPad. I made a short video to tell you’re about it, and I’ve included an extended transcript afterwards.
Hello Folks this is Steve from the iOS Development Tips Weekly series on lynda.com and LinkedIn learning. A lot of the weekly tips using Swift playgrounds for iPad and much of the course material in the course I wrote Learning Swift Playgrounds Application Development uses a technique to get a view controller showing on the live view. Well I just had the current Swift Playgrounds 2.1 update from April 30 2018, cause chaos on my iPad Playgrounds, killing all my playgrounds with this lovely message every time I run something that worked before the update:
Let me show you what’s going on, and an easy workaround for it.
I’ve got on this iPad playground the code as I’ve always written view controllers to the liveView
.
import UIKit import PlaygroundSupport class ViewController:UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .blue } } // launch the live view let vc = ViewController() PlaygroundPage.current.liveView = vc
You make a view controller. For something simple, In viewDidLoad
I changed the background color of the view. Under the ViewController
class I assign ViewController
to vc
, then set the current playground liveView
to vc
.
I’ll run this and you’ll see you get that error which doesn’t tell you much. Try this with the step through and You’ll see it fails on the line view.backgroundColor = .blue
.
I did some digging on this. I appears in viewDidLoad
the view does not yet exist — even though it is supposed to. This only happens on the iPad app in 2.1. On Xcode playgrounds and Version 2.0 of the iPad app, it works fine.
I also found this bug only occurs on the first view controller. There’s a few workarounds which launch ViewController
later and avoids a the problem if you launch something first that doesn’t access the view of the view controller.
The simplest is to embed the controller in a navigation controller. In Swift playgrounds, that’s two or three lines of code. To embed the controller, after let vc = ViewController()
, add this to embed vc
into the Navigation controller:
let navigationController = UINavigationController(rootViewController: vc)
Then change the liveView
to navigationController
:
PlaygroundPage.current.liveView = navigationController
Run this and the live view turns blue, but with a navigation bar.
If you wish to get rid of the navigation bar, add this line:
vc.navigationController?.isNavigationBarHidden = true
so your code looks like this:
// Set up live View let vc = ViewController() let navigationController = UINavigationController(rootViewController: vc) vc.navigationController?.isNavigationBarHidden = true PlaygroundPage.current.liveView = navigationController
Run again:
This has the added benefit you can use navigation controllers in code of course. If you want to learn more about using navigation controllers in code, you can check out this tip.
If you don’t want to use a navigation controller, there is a second way of handling this. You can use a launching class that presents your view controller modally. Add the following class to the playground:
class StartViewController:UIViewController{ override func viewDidLoad() { super.viewDidLoad() //uses global vc, you might want to encapsulate more. present(vc, animated: false, completion: nil) } }
I set animated
here to false
so you don’t see the launch. Launch the live view with this:
// Set up live View let vc = ViewController() // set up properties of vc here let startVC = StartViewController() PlaygroundPage.current.liveView = startVC
And you’ll get the blue background
I did report the bug to Apple, and we’ll see what happens. If you liked this tip, check out my iOS Development Tips Weekly dropping every Tuesday afternoon on lynda.com and LinkedIn Learning.
Leave a Reply