Apps that stand out must be attractive, intuitive, and easy to use. Interface Builder experts will give you the skills to turn your idea into a world class app. Learn to use the new stacks feature, create adaptable interfaces, employ asset catalogs, and design custom UI to build an outstanding app for Mac, iPhone, iPad and Apple Watch.
KEVIN CATHEY: Good afternoon, welcome back from lunch.
I guess if you guys are watching the video you are like, lunch,
I'm eating breakfast right now.
Or whatever meal you just ate, wherever you came from,
welcome to threading issues with core data.
I'm just kidding.
No, we are here to talk about interface builder.
My name is Kevin Cathey I'm one
of the interface builder engineers and we're going
to do something a little different today,
we're going to show you some of the new features
of interface builder but I want to do two other things, one,
we're going to give you some more advanced content,
tips and tricks, best practices, interface builder
under the hood, and then second we're going to look
at interface builder and how it helps you through each step
of the development of your application.
Let me explain a little bit more.
Here is you.
You have a bright idea.
Now, thankfully there are some other people
who also think your idea is pretty bright too,
but here is the problem.
They live all around the world
and they use all different kinds of Apple products.
What are you doing to do?
First you're going to think about your application,
what are the features it's going to have?
What will be the different clumps of shared functionality
that you're going to have?
When you have those you will look at an individual scene
and within that scene you will go down
and actually work at the view level.
Okay so if we step back for a second,
going from a view all the way up to deploying multiple products
in languages, that's a huge process
and interface builder helps you save boat loads of time
in each one of those steps.
We can take this entire process and boil it
down into three main phases which works out great
for an agenda for the session.
We're going to start by talking
about interface builder at design time.
I'm going to give you guys some best practices
and then we're going to pull the hood up a little bit and look
at interface builder at build time,
and then finally we're going to spend a large section
of this presentation talking about interface builder
at run time, both how you can interact with interface builder
at run time and also how can you take advantage of many
of the different run time OS features
for making applications adaptable.
Let's dive in and start talking about interface builder
at design time and the best way to talk about interface builder
at design time is to show you interface builder
at design time.
Now, before I switch over to the demo here,
in this demo I'm going to show you five tips and tricks
and five best practices.
We're going to do that by adding a new feature
to an application we are working
on which is a road trip application.
We're going to add a new tab to it that allows me
to follow my friends who are currently going on a road trip.
In this application, I'm going to be working off
of a specification from my designer, and I'm enjoying this
for two reasons, one if you are working with a designer
to help maybe give you guys some of the lingo
that you might interact with when working with a designer,
and then secondly if you're not working with a designer
to show you that building applications
and the best processes going into that can be done with
or without a designer.
With a static mock up like the one you see
on the screen there's two main pieces of data you will grab
from this, one, the layout, where things go.
Two, the appearance, what things look like.
We're going to start by working on the layout
of the application, and that brings us
to our best practice number one, adopting auto layout
and specifically adopting stack views.
Adopting auto layout means taking the relationships
between views and co-defying those
in objects called constraints.
For those of you who have used auto layout in the past,
you'll know that working
with raw constraints is very flexible, very powerful.
It's some other things too.
For example, you will sometimes need to specify the same sets
of constraints repeatedly and that's
where stack views come into play.
If constraints are taking the old, you know, position
and size information and abstracting
that into relationships, stack view takes it a step farther
and takes those relationships and abstracts it into behaviors.
Let's go ahead and adopt stack view in our application.
Let me switch over to Xcode.
Here is the beginnings of our awesome new feature.
Adopting stack view in interface builder literally I don't think
it could be simpler.
I'm just going to select the views that I want to put
into a stack view and then using the stack button down here
in the bottom of the canvas, I just click it,
and now we have a stack view.
Once we have a stack view, we can adjust several
of the different properties that a stack view has.
Now, in tomorrow's auto layout session they're going to go
into all of the different properties that stack view has
but one that we're going to focus
on now is called alignment.
If I switch back to my mock-up,
you can see that my designer has specified
to baseline a line these labels.
What is baseline alignment?
Baseline alignment basically allows you to take text
that is different font sizes and make it look nice and aligned.
If you have textual objects like buttons and labels
and segmented controls you're going to want
to baseline align these versus using top or center or bottom.
So let's go back to interface builder and what we can do is
if I go into the attributes inspector I can change the
alignment of my stack view to be baseline aligned.
Now, there is first and last year,
so if you have multi-line text,
you can target either the first line of text
or the last line of text.
In this case it's single line so it doesn't really matter
so we'll go with first.
So let's continue adopting stack view, I can take this stack
in this label and put it in stack view
and I can add our image view.
As I'm embedding in stack view,
interface builder is automatically inferring the
different attributes such as the alignment and the orientation.
Now that we have this outer stack view we want
to position this within our table cell
which is not a stack view.
And to do this we're going to use raw constraints.
I'm going to go to my tie fighter and go ahead and open
up add constraints and I want to clarify two things
in this pop-up, the first is what is
up with the layout margins?
What are these things.
Layout margins are insets from a view
that by default the system provides some values for
and if you use the default layout margins they can be
automatically adapted based upon different context, for example,
the device or the view hierarchy.
Generally if you have content like buttons, labels,
things that people interact with or see, then you are going
to want to constrain things to the margins
if it's not constrained to another sub view.
If you have something like an image view that kind
of sits behind your entire table view cell
that makes perfect sense to constrain it
to the edges instead so even
if those margins change your imagery will still be
in the background.
If I uncheck constraints, constraints
and margins you can see larger values coming into play.
Interface builder defaults to margins which is helpful
because that's exactly what I want.
Second thing I want to clarify is this update frames here
which I am going to use.
Update frames is the process
of interface builder moving your views in the IB canvas
to match what the constraints would be at run time.
When I'm adding constraints I have a couple
of options for doing this.
If I say all frames in container it means for all
of the sub views in my table view cell,
move them to where the constraints would tell them
to be at run time.
However, if I have a really large view with lots and lots
of sub views, I might only want to move the things
that I'm currently working on at that instance,
and that's what this middle option is,
it only moves the items that are actually going to be
in the new constraints I'm adding.
Now, I only have one thing so it doesn't matter
so we will do all frames and add those constraints
and now we are on our way.
Okay. Next thing I want to do is change the alignment
of the items inside the stack view.
Another example of doing that.
I will change that to fill and now,
that's not exactly what I'm looking for, right?
Stack views are built on top of auto layout,
which means that you can use constraints
to fine tune your layout.
So if I want to make this image view have a one-on-one ratio,
even though it's in a stack view,
I can still add constraints so I can add an aspect ratio
and then change the multiplier to be one to one.
The next thing I want to do is add spacing in between
that image view and the right hand content.
Because my designer would like there to be some padding there.
Now, the stack view that I need to change the spacing
on is fully occluded by labels and other stack views?
How can I get at it?
There are a couple of ways you can get
at occluded views in interface builder.
I could use the jump bar or I could use the outline view,
but I'm going to show you my personal favorite
which brings us to Xcode pro tip number one
which is fast selection.
If I shift right click or control left click.
I can get a menu of everything underneath the mouse
at that point and then I can easily select the thing
that I'm looking for.
Once I have it selected I can change the spacing
to what I need and there we go.
The last thing I want to show you
with stack view is how you can use multiple stack views nested
together to get the exact layout you are looking for.
If we go back to our specification here,
you can see this set of labels our designer would like it
to act as a unit and be centered vertically
within the table view cell.
We can do this by putting the right hand content
in another stack view and adjusting the alignment.
Let me show you that.
I will use my fast selection again to get to the stack view.
I'm going to embed it in another stack view.
You can see the blue got a little darker to show you that,
and now I can change my alignment to center.
Now, alignment affects the non-stacking direction.
Because this is a vertical stack view,
it's going to be adjusting the horizontal alignment,
but I want to affect the vertical alignment
so I will change the access to horizontal.
And you can see with stack views I can get the exact layout I'm
looking for with very minimal constraints.
Our recommendation when adopting auto layout is
to use stack views and to try to use stack views first
and then only when you need to actually use raw constraints.
We think you're going to be able to build most
of your UIs using stack views.
Which makes it easy to build.
It makes it really easy to experiment
with different layouts without having to adjust a bunch
of constraints and it also makes it very maintainable
when you go back in later and have
to edit one of your documents.
The next thing we want to do is start looking
at the appearance of our application.
And the first thing I'm going
to do is prepare our canvas for some design time.
To do this I'm going to go under the edit canvas menu.
And interface builder has lots of options
for customizing what's drawn on the canvas.
For example, these blue backgrounds the stack view is
drawing for me are really helpful at layout time
so I can see exactly how big that stack view is going to be,
but at design time I want to see what it's actually going
to look like at runtime.
So I will just go ahead and turn those off.
Okay. In the appearance section of this demo, we are going
to look at three best practices with using interface builder.
If we go back to our specification,
we'll see the first one.
Our designer has specified headline and body instead
of an explicit font or font size.
What are these?
These are called dynamic type styles.
They are defined by the system and when you use them,
it allows the system
to automatically adapt what the effective size and font is going
to be at runtime based upon your user's preferences.
For example, the user can adjust accessibility
to have a larger font.
Your application when using dynamic type will automatically
adapt to those font changes and if you are using auto layout,
the views will all flow around it.
So we can adopt this really easily inside
of interface builder.
I can just select the label I want to adopt dynamic type for
and the inspector, I can pick one
of the font styles instead of an explicit font.
In this case, I will choose headline.
I have already adopted it for the rest of my labels
so we are done with dynamic type.
The next thing we are going to do is we are going to bring
that image view to life and we are going
to use two best practices for this.
One is designables, and two is inspectables.
Designables allows us to see our custom drawing code right inside
the interface builder canvas.
So let's go ahead and get some code for that.
I want to go ahead and open up the product navigator.
Let's add some files.
Tony, who is going to come
up later just air dropped me this code, so let's go ahead
and add that to our project, and I'm going to go ahead
and open this, and in opening it,
I'm going to show you guys Xcode pro tip number three,
which is advanced navigation.
If I option shift click this file, I get a little hud.
This hud allows me to target where I want to open this file.
So I can choose a new tab, I can choose a new split.
If I have multiple tabs I can even target specific splits
within tabs that aren't even open.
And as I use command I can also even open it in a new window.
In this case, I'm just going to do the assistant editor.
Adopting designables is a really simple two step process.
All you have to do is mark a subclass of UI view
with IB designable, and then set that custom class
with an interface builder.
So if we select our image view or what's going
to be our image view, change the identity inspector,
and add in our customs subclass here.
Interface builder is going to build my project,
launch a process for rendering, bring in my code, render it
and show me that in the canvas.
And if I change the code,
it's going to automatically take those new changes, build them,
and apply them within interface builder as well.
The next thing I want to go is adopt inspectables.
You can see I have a couple different properties here marked
add IB inspectable.
When you mark a property
as IB inspectable it allows interface builder
to generate an inspector for you.
If I select image view, go to the attributes inspector,
you can see that those three properties I marked
as inspectable are showing up now in our inspector
and we can quickly adopt these.
So I can say I'm going to add that little image there.
We're going to do our stroke with.
I think the spec said two, if I recall correctly.
And we can give it a nice border color as well.
Now, what's going on here is that designables
and inspectables are working together
to help you rapidly iterate on your design.
I haven't built and ran once and I can see exactly what I'm going
to get at runtime because of the power
of designables and inspectables.
And that's our section on adjusting the appearance
of our application with the dynamic type,
designables and inspectables.
Now, we all know that our applications are not made
up of a single scene, okay,
unless you write the flashlight app, but generally you're going
to have multiple scenes in your application.
And if I zoom the storyboard
out I can see there is a lot more scenes in my application.
You can bring a scene into the flow
of your application using segues.
To make a segue I can control drag from a view controller
or an object that can initiate a segue and select the type
of segue I want to add.
In this case I will add a relationship segue
to add another tab to our tab bar controller.
Now, once we actually have made the segue, I realize that I kind
of want to be able to navigate
within this table view controller, so I am going
to embed this in a navigation controller.
I will choose the editor menu,
embed and embed this inside a navigation controller.
I want to point out something
that interface builder is doing to help us here.
This is another Xcode pro tip.
Interface builder is showing us a nav bar and a tab bar
for this particular scene.
Now these objects are not added to the scene,
interface builder has not added these to your scene
but what it is doing is helping you see what your application is
going to look like at runtime given some context.
This makes it really easy to be able to design
for different contexts without having to build and run.
You can see what your simulated metrics are, which is the name
of the feature, by selecting your view controller.
And then going to the attributes inspector
and you can see my simulated metrics.
Now, right now they are all saying inferred.
Inferred just basically means use the context around me.
We know we are inside a tab bar controller,
we know that we're inside a nav controller
so interface builder knows which bar to show.
I can override these to be whatever I need.
So, for example, I could say actually I want to look
like what is it going to look like with prompt
if I had prompt text in there?
What if the top bar was black.
I will put this back on inferred.
All of these metrics do not affect your actual application
at runtime with one exception
and that's the size simulated metric.
The size simulated metric will actually change the size
of your view controller but generally you're going to put it
into a view controller hierarchy which will resize it,
but it's also helpful if you are creating free form view
controllers, for example, and want to set your own size.
It's also helpful if you are wanting to be able to design
with a specific size in mind even
if your application is going to run on multiple devices.
The spec I was given was for iPhone 6 Plus, so I can change
to a 5.5 in screen size and be able to edit
as if the view controller was going to be that size.
There's other features
of interface builder we are not going to talk about today
which allows you to see what your view controller will look
like on multiple devices
at the same time using the preview assistant,
but this is really helpful for just being able to edit
with a particular context in mind.
Let's go back to inferred
and let's finish off our view controller.
Give it a title, your friends.
Let's add some bar button items.
We had add one for being able to invite a new friend.
And with Xcode 7 I can add multiple bar items
to my navigation item.
It's the small features, right?
Let's finish off this by adding a segue
to present this guy modally, and if you zoom
out we have a great start to your application.
Just like I would refactor my code
into separate files based upon the reuse of it
or related functionality,
I can do the exact same thing now with interface.
If I just select the view controllers that I want and go
under the editor menu, I can select refactor to storyboard.
You can type in a name, I will call it follow
because this is our follow tab.
Interface builder is going to create a new storyboard,
move those view controller scenes into the storyboard
and put a reference to the scenes in the old storyboard.
Now, it's really easy to collaborate with storyboards.
And it's the big features.
Let's go back to slides.
We have looked at a number
of different things here so let's recap.
I have given you five best practices.
We have adopted stack views and dynamic type
to make your applications adaptable.
We have adopted designables and inspectables to be able
to rapidly iterate on your design
without having to build and run.
And finally we have used storyboard references
to make sure we are properly modularizing our interface just
like we would do for our code.
I have also given you a couple of tips
that I hope you guys are going to find useful
as you're using interface builder like being able
to select things, being able to customize the canvas,
open files exactly where you want them using multiple bar
items and, of course, taking advantage of simulated metrics
to see at design time what you are going to get at run time.
But what happens when I hit build?
Let's talk a little bit about what interface builder is doing
for you at build time.
Now, to do this we are going to have to take a step back
and look again at design time
and where we are going with run time.
At design time you are working with XML documents.
At build time a process called IB tool takes these documents
and compiles them into nib files.
Nib files are small, very optimized binary files
and it uses a process called keyed archiving
for creating these.
I have a few examples of what this could look like.
When interface builder is compiling a storyboard it's
doing two things first,
it's trying to maximize the performance of your application
and secondly it's also minimizing the number
of nib files created.
If I have a view controller with a view and a bunch of sub views,
interface builder, the build time is going
to create a nib file for the view controller
and create a nib file for the view.
Why two nib files.
By having separate nib files for both the view controller
and the view, this means the view hierarchy can be loaded
With this other example here, with the table view controller
and navigation controller things get even a little
Again, interface builder is trying to minimize the number
of nib files it's creating with a relationship segue we know
that those two view controllers go together,
so we will put those in the same nib.
Next we are going to give you a nib file for the table view
and also a nib file for each of the cells.
So how does this play out at run time?
When you allocate a storyboard instance using UI storyboard,
API, initially all you are allocating memory
for is the UI storyboard instance itself.
No view controllers no views yet.
When you instantiate your initial view controller it will
load the nib for that initial view controller but, again,
no view hierarchy has been loaded
yet until someone actually asks for it.
Similarly, if I gave that navigation controller
and table view controller an identifier then I could use the
instantiate API to be able to get
that view controller instance, but, again,
the view has not been loaded into memory
until someone actually asks for it.
How about those table view cells?
This is where it gets fun.
So interface builder is going
to automatically take table view cells, nibs, and register them
with the table view under your reuse identifier
that you set, that table view cell.
Now, what this means is that these cells are not going
to be loaded until someone actually DQs the cell
with the identifier.
Now, it also means that once the nib run time has loaded
that nib file into memory, it can rapidly instantiate it.
So there are a couple of take aways for talking
about interface builder at build time.
The first is performance.
Interface builder is working on your behalf
to make the performance of your applications as good as we can.
Nib files are only loaded on demand
and nib files themselves are really small and optimized.
Secondly, interface builder has reuse of different nib files.
For example, on the table view cell that's we saw,
once the runtime has the nib file it's able
to reinstantiate it very very quickly as new cells are needed.
Finally hopefully you can see the lifecycle
of how things are happening between build time and runtime
so you know how to interact with the different objects
like your view controllers and your view hierarchies.
We talks about interface builder at design time.
We have pulled the hood up a little bit at build time,
but we're going to spend the rest of the session talking
about interface builder at runtime and what happens
when you have all those different products
To do that, I'm going to bring up my colleague, Tony Ricciardi.
TONY RICCIARDI: Thank you Kevin.
My name is Tony, and I also work on interface builder.
So Kevin just gave you some great best practices
for building your UI at design time and then he gave you a peek
at what happens behind the scenes at build time.
Now, I'm going to give you a few examples
of how you can add dynamic behavior to your UI at run time.
Interface builder supports three general mechanisms
for controlling your UI at run time.
First of all, you can create connections
between your storyboard and your source code using IB actions
and IB outlets.
You can also customize the behavior of your segues
or dynamically instantiate
and add view controllers using the storyboard API.
And finally, you can use auto layout or size classes
to specify how your UI adapts as the size
of its container changes.
Let's start with connections.
In Swift, IB outlets are
by default implicitly unwrapped optionals.
If you have an outlet between a view controller and one
of the views in its hierarchy you can safely unwrap
that optional after viewed load.
Sometimes you will have an additional property stored
on your view controller that affects the appearance
of that view, and in that case, you will want to unwrap
that property using optional chaining
within the did set observer of that property.
In case your outlet hasn't been connected yet.
IBAction is allowing you to respond to events sent
from gesture recognizers and controls.
You might use an action just to update some state
without navigating away from the current view.
You can also use an IBAction to dynamically choose
which segue you want to perform after an event.
Next we have the storyboard API.
The class UI storyboard or NS storyboard on the Mac allows you
to grab a reference to a storyboard file
and instantiate view controllers from that storyboard.
It's extremely useful if you have a reusable piece
of UI you want to repeatedly instantiate.
It's also the only way you can connect multiple storyboards
in your app if you are displaying prior
to iOS 9 or Mac OS 10, 11.
We also have a lot of great API hooks on UI controller
to allow you to customize behavior of your segues.
This year we have made a lot of improvements
to segue unwinding on iOS.
We have made it a lot easier to subclass UI storyboard segue
or NS storyboard segue.
If you would like to learn more about that,
please come to our What's New
in Storyboard session tomorrow morning.
Finally we have adaptability.
Interface builder supports two technologies
to help you adapt your UI to different container sizes.
First of all, we have auto layout which allows you to size
and position your views relative to each other
so that you are not relying on hard coded frame values.
In some situations, you will want
to make a significant change to your layout as the width
or height of the container crosses a certain threshold,
and in those situations we have another great feature called
size classes which makes that very easy to do.
Now, I would like to give you a demo
of how you can apply these three general techniques to work
with interface builder at run time.
Let's head over to Xcode.
Today we will be building a UI to keep track of the activity
of your friends on their Roadtrip and plan
on integrating this into Kevin's Roadtrip app later on.
As you can see in this UI, I have three rows of posts,
and within each row, I show the top three posts
from that category.
If we take a look at the storyboard for my app,
you can see I have implemented this UI using a stack view.
Within this stack view, I have three container views.
A container view allows you to embed one view controller inside
of another one, and that's extremely useful
if you have a reusable piece of UI like this that you want
to use multiple times within the same scene.
My embedded view controller
over here has a stack view of its own.
In this stack view holds multiple instances
of this post view controller down here.
The number of posts that I show in each category is controlled
by a user setting and so I don't know it statically
at design time.
Instead of using container views like I do over here,
for this view controller,
I instantiate it using the storyboard API.
I refer to this view controller
from code using its storyboard ID up here which I have set
up here in the identity inspector.
Let's take a look at the code where I do that.
I'm going to use the jump bar to navigate to the source code file
for my post stack view controller.
So you can see down here
in my view.load method I'm using the storybook API instantiate
that post view controller.
Specifically, I'm using the storyboard property
that I'm getting from UI view controller
and then I'm calling instantiate view controller with identifier.
And that identifier I pass in is the same string we just saw
in the identity inspector.
After I add or after I instantiate the child,
I add it as a child view controller.
And then I add it's view
as an arranged sub view of my stacking.
So the storyboard API is great for instantiating
and adding a child view controller, but what if you want
to add a sub view that is not associated
with a different view controller.
Let's head back to the storyboard for an example.
If we take a look up here at the top
of my activity view controller, you can see I have a view
up here in the scene doc.
The scene doc allows you
to store top level objects alongside your view controller
and you might put a view in your scene doc if you don't want
that view to initially be part of your view at run time.
In Xcode 7 when you put a view in your scene doc
and you select it, it shows up in its own editor
above the view controller.
This means you can now visually edit your views right here
in the storyboard canvas, even if they are not initially part
of your view hierarchy.
This view here shows an error message
if there is a problem connecting.
So what I want to do now is create an outlet connection
to this view and then add it from code
if there is a problem connecting.
I want to open up the assistant editor and that's going
to take me to the implementation for my activity view controller.
And then I'm just going to control drag
over to the source code and when I let go, I get a little pop
over allowing me to configure my outlet connection.
But -- the first option here is whether I want
to make an outlet or outlet collection.
Outlet collections are great for adding or removing groups
of sub views or constraints all at once, but in my case,
I just want to add a single view,
so I'm going to choose outlet.
Next we can name the connection.
I'm going to call it connection error view.
And the last option I want to point out is the storage type,
which can either be strong or weak.
In general you should make your outlet strong,
especially if you are connecting an outlet to a sub view
or to a constraint that's not always going to be retained
by the view hierarchy.
The only time you really need to make an outlet weak is
if you have a custom view that references something back
up the view hierarchy and in general that's not recommended.
So I'm going to choose strong and I will click connect
which will generate my outlet.
Now, I'm just going to paste in some code,
and this code is an implementation of view did load.
And I check if there is a problem connecting and if it so,
I add my connection error view to the top of my root stack view
and I'm accessing both views using outlets.
Let's take a look at this in the simulator.
So as you can see, there was a problem connecting,
and now my view is showing up right at the top as we expected.
So this UI looks great on a full screen iPad.
What happens if I run it in split view?
I'm just going to drag the split to be in the middle
of the screen and let go,
and you can see my UI is not doing a great job
of adapting to the narrow width.
What I really want is for these posts to lay out vertically
when the width is compact
so that each post can get the full width
of the screen to itself.
And at the same time, when we are back in full screen mode,
I want my stack views to continue to lay
out horizontally like they are now.
So to do that, I'm going to head back to my storyboard,
and I'm going to close the assistant
to give us a little more room.
And I'm going to select my stack view and head
over to its attributes inspector.
You can see currently my stack view is configured to lay
out horizontally, and next
to this access property there is a plus button.
This plus button allows you to add a size class customization.
A size class is an abstract range of sizes in one
or two dimensions and in my case I want
to customize this property for when the width is compact.
And since I don't care about the height dimension,
I will choose any height.
When I do that, I get a new row in my inspector
and the value I put here is going to take effect
when the width is compact and the height is anything.
I will change that to vertical now.
And I will run this again.
So once again we are in full screen
and our stack views are still laying out horizontally.
Now, let's try this in split view mode again.
We got it.
So there you go, now our accessory view is laying
out vertically like we wanted
and each post gets the full width of the half screen.
So that was just one way you can use size classes.
You can override a property value for single property,
but you can also add and remove entirely new sub views
or constraints, and if you want to learn more
about all you can do with size classes,
we had a fantastic session
on that last year called building adaptive apps
with UI kit.
That's all I have for the demo,
so let's head back to the slides.
Kevin and I just showed you a ton of great techniques
to help you get the most out of interface builder.
Let's review the most important ones.
First of all, you saw how you can build flexible user
interfaces that don't rely
on hard coded frame values using auto layout constraints
and stack views.
Then Kevin showed you how you can rapidly iterate
on the appearance of your custom views using designables
We introduced a new feature
to help you modularize your UI called storyboard references,
and then I showed you how you can use the storyboard API
to repeatedly instantiate reusable components.
And finally, you saw how you can make your UI adapt
to different container sizes using size classes.
If you would like more information, you can post
on the forums or contact our evangelist
and we also highly recommend checking out our What's New
in Storyboard session tomorrow morning as well
as our two auto layout sessions later that day.
Once again if you want to learn more
about size classes please check
out our building adaptive app session from last year.
And finally if you want to learn more
about troubleshooting your auto layout
within Xcode we had a great session on that in 2013.
And thank you all and please enjoy the rest
of the conference.
Looking for something specific? Enter a topic above and jump straight to the good stuff.
An error occurred when submitting your query. Please check your Internet connection and try again.