Developer Tools • iOS, macOS • 14:13
Easily prototype and play around with SwiftUI views when you use them with Swift Playgrounds. We’ll show you how to build a SwiftUI view in a Xcode-compatible playground, and explore tools to help you easily edit and preview your code. For more on Swift Playgrounds, check out our interactive challenge, “Swan's Quest”, and learn to build your own by watching “Create Swift Playgrounds Content for iPad and Mac”.
Speaker: Matt Patenaude
Downloads from Apple
Transcript
Hello and welcome to WWDC. Hi. I'm Matt, and I'm the engineering manager of the Swift Playgrounds team, and today I'm going to be walking you through the process of using Swift Playgrounds to prototype a SwiftUI view. Many people know Swift Playgrounds as a great way to learn to code using Swift. What you may not know is that it's a full-featured environment for prototyping and coding in Swift far beyond the end of the "Learn to Code" series.
Today we'll start out by creating a Playground that's compatible with Xcode and showing a SwiftUI view as the Playground's live view. We'll take a tour of some of Swift Playground's unique editing features that can make prototyping faster and easier, and we'll look at how to move your code into multiple source files for building more complex Playgrounds. Lastly, we'll look at a couple of tricks for building custom, interactive previews with more than one SwiftUI view at once.
So, as so many engineers do at one point in their lives, I'm working on building a task-tracking app, with tasks grouped into milestones for a particular project. One thing it's missing, though, is a nice summary of my progress through the project as a whole. I want to do a little something like this.
Now, clearly my hand-drawn art isn't quite ready for prime time, so we're going to build this view using SwiftUI, and I'm going to do it in a Playground. Today I'm using an iPad with a Magic Keyboard attached, but you can do this just as easily using the on-screen keyboard or using Swift Playgrounds on Mac.
Since I know I'm going to be bringing my work into Xcode when I'm done, I'm going to create a blank Xcode Playground rather than a blank Playground book. I do that by tapping the "See All" button in the bottom right-hand corner, scrolling to the end of the starting points, and then tapping "Get" next to Xcode Playground, which will create a new, blank Xcode Playground in the top left corner of the My Playgrounds screen.
I'll give it a more interesting name before we start, which I can do by tapping and holding, or in my case, two-finger clicking on the Playground, choosing "Rename," and then entering a new name. We'll call it "My ProgressView." I'll tap "Done," and then I can open the playground by tapping on it. And we're ready to start coding. Since I'm building a SwiftUI view, the first thing I'll do is import SwiftUI.
I'm also going to import the PlaygroundSupport framework, which is what you use to customize the behavior of your Playground, including showing live views. Next, we'll create our view, which is going to be a struct called ProgressView. It'll conform to the "View" protocol... and it'll have a property called "body," which returns an opaque view type.
For now, let's just say "Hello world." We're ready to show our view now, so I'll move to the end of the document, and I'll use the PlaygroundPage type to access the current page and then call the setLiveView method. Now, you might have noticed that while I've been typing, I've been getting completion suggestions at the bottom of the screen. I can either tap those with my finger, or in this case, I'll click using the trackpad... and then I'll create a new ProgressView.
To see what this looks like, I'll tap the Run My Code button in the bottom right-hand corner of the screen. And voilà! Our first SwiftUI view. Now, this text is just a placeholder, and I think we want to get started by building out the basic shape of our live view, which, if you remember from my crudely drawn mock-up, is kind of a circle-y type shape. So I'll delete the text that I've written here... and replace it with a Circle view.
The arc in the mock-up has a blue stroke on the outside of it, so I'll use the stroke modifier... and start typing "line width." Then I can tap the first suggestion at the bottom of the screen to complete it. For now, let's say "25." And since I like to indent my modifiers below the view that they belong to, I'm going to use the Command-Right square bracket keyboard shortcut to indent the code. We'll also want to give this a foreground color, and we'll set that color to blue.
We can look at this by running it, which this time I'm going to do using the Command-R keyboard shortcut. And there we have it. A blue circle. I'll admit, it's a little bigger than I thought it was going to be, and that stroke isn't quite as heavy as I imagined either, but that's pretty easy to change. For the stroke width, I can single-tap or double-click on 25 to select it, and we'll say maybe 40 instead. And we can give the view a little padding by adding a padding modifier of maybe 150.
If I hit Command-R again, this time it looks a lot closer to what I had in my head. The next thing we'll build is the text in the middle that tells us how far we are through our project as a percentage, so I'm going to add a Text view to contain that text and then put it in a ZStack with my circle.
I'll click above the circle, type "ZStack," and create a pair of curly braces. But rather than move my code inside of those braces manually, I can tap on the ending brace, or in this case hover my pointer over it, press and drag down to encompass the circle and its modifiers.
Finally, we'll add a text view, and for now, we'll just hard-code "25%." If I hit Command-R... Looking good. We're really cooking now and making great progress through this view. -So it's time to get... -[computer dings] Oh. Well, I guess our designer has actually already done -all of the hard work for us. -[computer dings] It looks like they've started their Playground and put it in a shared iCloud folder. So I'll close this document by tapping the X button in the top left-hand corner, and I can access files outside the Playgrounds folder by tapping the "Locations" button. And there it is. So I'll open that... and then I'll tap the Run My Code button.
And you can see, yeah, they got a lot further along than I did. In fact, it looks so good, I'm not sure what they want me to change about it. -It's pretty perfect. -[computer dings] Oh. Okay. So it Looks like they want us to try tweaking with the colors a bit, so let's see if we can't make this look a little snazzier.
It's really easy to play with colors in Swift Playgrounds because it has an awesome built-in color picker. So, you can see on this line here at the top of the screen, we have the two gradient colors, which are the SwiftUI colors blue and purple. The Color type actually has another initializer that'll take a UIColor, so I'll use parentheses to open that... and if you look at the bottom of the screen, one of the options there is this gray square that represents a color literal.
When I insert it, I get a color picker with tons of options provided by Swift Playgrounds. I think we'll pick this nice raspberry color for the first one, and then for the second color, we'll follow the same steps. I'll open the parens, insert a color literal, and this time pick a nice deep purple.
And now if I hit Command-R, you can see it looks a lot livelier than it did before. I think we're really about done with this now -and ready to wrap it up. -[computer dings] Unless, of course, our designer has other ideas. And they have a great suggestion, as always.
We should see what this looks like in Dark Mode. Now, one of the great things about working with SwiftUI in Swift Playgrounds is that this entire live view area is your canvas, so if I want to show my view more than once, I can do that really easily.
First, though, I want to give myself a bit more breathing room in the main page, so we're going to move ProgressView to a file all of its own. I can add a new file by tapping on the "File" button in the top left-hand corner, or on a Mac, by opening the sidebar, and then tapping the "New File" button.
I'll give it the name "ProgressView," press "Return" to accept it, and then I can tap outside the popover to close it. And here we are: a new empty file in its own tab called "ProgressView." I'll switch back over to the main page, and now what I want to do is move this entire ProgressView struct over into the file we just created.
I can do that by single-tapping or two-finger clicking on the "struct" keyword, and then choosing "Cut." I can then switch back over to the ProgressView tab with the Command-Shift-Right Brace keyboard shortcut, tap to enter code, and then press "Command-V" to paste. And there we have it. It's in a file all its own. Right away, you can see it has some issues, though, and the biggest one is that I haven't yet imported SwiftUI into this file. So I'll do that.
I'm also going to want to mark my struct "public," since it's now in a separate module, so I'll do that as well. Now that I've done that, you can see there's one new issue for us to address, and if I tap on the "issue" dot, it's reminding me that "body" needs to be made public as well. I'll tap "fix" to accept the fix-it. And while I'm here, I'm also going to mark the initializer as public, because I'm about to use it on the main page.
I can use Command-Shift-Left Brace to switch back... and if I hit Command-R... you can see the live view is unchanged. Now, I want to look at two of these at the same time so I can compare what it looks like in Light Mode versus Dark Mode, so to do that, I'm going to create a new view to act as my preview. We'll create a struct called "Preview"... that conforms to the View protocol like before. And in this case, the body is going to be a VStack.
We'll add a little bit of spacing... and inside it, we'll create two ProgressViews. While we're at it, I'm going to spruce it up a bit so it looks nice. I'm going to get rid of the padding we specified down below using Option-Delete to delete by word... and then I'm going to add some padding to the VStack.
I'll also add a background modifier so it's easier to see differences between Light and Dark Mode variants of our view. Here I'll use a color, and I'll pass in the UIKit... secondary system background color, which I'll let code completion fill in for me. Lastly, we'll switch the ProgressView initializer at the bottom of the file to our new Preview initializer by single-tapping or double-clicking its name and typing "Preview." I'll use Command-R to run, and you can see that now I've got two different previews of our ProgressView. I did want one to be in Dark Mode, though, so for the second one, I can add an environment modifier, and we'll set the color scheme... to dark.
Now when I hit Command-R, you can see we have one in Light Mode, one in Dark Mode. Looking great. The last thing I want to do is take a look at how this view feels in action with different progress values and with animation. Since the live view is fully interactive, I'm going to do that by adding a button to step through different values in 25% increments. I noticed that the ProgressView accepts a double as an argument to its initializer, so let's wire that up in our preview.
I'll create a new State variable called "Progress," and I'll set that to 25%. I can then pass that into each of our ProgressViews... and when I hit Command-R, the value updates. With that in place, we can now add our button. I'll create a new method called "Increment," which is just going to add 25% to our current progress value.
And since I did promise animation, we'll add a "with Animation" block on top of it... and like before, drag the closing brace to encompass our incrementing statement. Now I'll create a new button view inside our VStack... and I'll set its action to the method that we just created.
Lastly, we'll give our button a label, which is just going to be a Text view with the message "Increment Progress." If I hit Command-R now... you can see we have a new button, and if I tap it, we have a working ProgressView. And that's building a SwiftUI view using Swift Playgrounds.
In summary, Swift Playgrounds has loads of features, like color literals, brace dragging, and a full suite of keyboard shortcuts that make it easier to edit complex code. If you're going to be bringing your work back to Xcode, it usually makes sense to start with the Xcode Playground starting point.
You can split your code across multiple source files to make it easier to understand. This is especially useful with SwiftUI views, where you can put your view code in a module and use your main source file for previews. And remember, you can customize your previews and add interactivity by creating your own views just for that purpose. Thanks for watching, and enjoy the rest of the awesome content from WWDC.