0: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.
0: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:
1: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:
2: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:
3: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,
5:15 The form elements are too tight. The rootStackView holds all the
elements, so we can simply set spacing on it:
6: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
6: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:
7: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 XCode, we add a Cocoa Touch framework as a new target to the
project's build settings.
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
17:23 The storyboard has a disclaimer label for terms and conditions as
an additional UI element. 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
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
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 30 percent longer words than 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.