00:06 Today we're joined by Brandon from Kickstarter once again. Together we'll build an interface in a playground and then move it into a framework that can be used in an actual application. At Kickstarter, the developers only construct a basic view hierarchy in Interface Builder, whereas all of its styling is done in a playground.
00:47 We've prepared a view controller that will serve as a sign-up form. It features a header, three input fields, and a submit button, all contained in a root UIStackView:
01:36 Our first improvement of the view controller is to style the submit button, because it's barely visible now. To do this, we'll give it a background color and make the corners rounded. These are pretty simple changes, but it's nice to see the live view updating. In viewDidLoad, we add the following:
02:25 Next we'll tweak the form's text field labels to improve the UI's hierarchy, because it'd be better if the input labels' fonts are smaller than the title font. Before, we'd set the font size explicitly with UIFont.systemFont(ofSize:), but it's better to use UIFont.preferredFont(forTextStyle:) and choose a semantic text style:
03:33 With another overload of this method, we can request the font that's suited to the view controller's current trait collection, so it'll adapt to screen size, orientation, accessibility settings, etc.:
05:15 The form elements are too tight. The rootStackView holds all the elements, so we can simply set spacing on it:
06:00 We paste in the remaining styles: a preferred font for the title label and the submit button, and a different text color for the button's highlighted state. Because we're working in a playground, we can actually click the button and see it changing colors:
06:20 The real power of working in a playground is the ability to dynamically swap the view controller's trait collection. This allows us to test the view controller with the characteristics of different devices and orientations. We wrap the view controller in a parent view controller, which can override the trait collection. The playground's live view should now be the parent view. We also paste in some standard layout code, making the child view fill the parent view:
07:18 We'll let the parent view controller feed a trait collection to the child view controller. We can initialize a UITraitCollection for a particular trait, like contentSizeCategory, sizeClass, or forceTouchCapability. We can also pass in an array of trait collections, which is composed to emulate a specific device. We create a trait collection emulating an iPhone 6:
10:07 The developers at Kickstarter wrote a helper method called playgroundWrapper. This method takes a child view controller and some parameters and returns a parent view controller configured with the correct size and trait collection. We simply use a couple enums to describe the configuration we want to emulate:
12:10 It's easy to change parameters and test a smaller contentSizeCategory or set the device to .pad. The live view automatically updates with the correct layout.
Using a Framework
12:58 In order to use this code in an actual app, we need to create a framework. In the project settings in Xcode, we add a new Cocoa Touch framework to the targets.
13:46 This adds a directory to the project outline. We've prepared a view controller and a storyboard based on the code above, so we drag these two files into the framework directory and make sure to "Copy items if needed."
14:12 We've prepared a version of the signup view controller class with outlets for the UI components and everything made public. The storyboard has the most basic setup of the view hierarchy, without styling or even names put in the labels, which is something that's all done in the view controller.
14:43 Now we want to use the framework's view controller from within the playground, but before we can do so, we have to build the framework.
14:58 We can now import the framework in a blank playground page. We need access to the Storyboard, from which we'll instantiate the signup view controller. We can initialize a UIStoryboard from both its name and a Bundle:
17:23 As an additional UI element, the storyboard has a disclaimer label for terms and conditions. We can use this to see how styling works in the current setup. We go back into the framework's view controller and style the label:
18:09 With that, we build the framework. Switching back to the playground, we see the updated layout of the view controller. It's important to remember to build the framework so that the playground has the newest code.
18:44 Kickstarter does playground-driven development in its real app. By using this technique, Kickstarter can provide some entry points to customizing interfaces. This allows project managers or designers who haven't worked on the interface to test and play with the view controller while tweaking its parameters.
19:03 We look at a playground that shows off the user's dashboard of the Kickstarter app, which features various stats of the user's projects. The playground has some top-level variables that can be used to see how different parameters affect the interface:
19:51 It's even possible to switch the UI language — e.g. to German, which typically has words which are 30 percent longer than in English — in order to quickly check how the interface behaves in different localizations.
20:49 Playground-driven development allows us to see how the interface works in various configurations. As it's interactive, we can click our interface's buttons in the playground and see the various button states.
20:56 We've been playing around with playground-driven development and we're impressed with how smart and fun it is.