Transcript
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
[ Silence ]
>> Good afternoon, everyone.
How you guys doing?
Oh, that was weak.
Yeah, there we go.
[ Applause ]
I could have made
a joke and said
that was unowned but I won't.
So this session is
called "What's New
in Interface Builder" or,
as we were joking earlier,
maybe "What Isn't New
in Interface Builder."
We have all kinds of great
stuff for you guys today.
And, so, my name
is Kevin Cathey.
I'm one of the Interface
Builder Engineers and me
and my colleague Quinn,
who'll be joining us later,
are going to be walking you
through some of what's new.
Now we're going to
show you some stuff
that you might not
have seen yet.
And we're also going to go
into more detail about some
of the things that you have
seen so far at this conference.
So what we have today is...
conveniently falls into
a couple of themes,
themes that you're
going to be --
have been familiar with
so far in the conference.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
have been familiar with
so far in the conference.
The first one is Liveness.
Now I don't know about you but I
like seeing what I'm working on.
And so as I work on my
code we have features
to bring your content, your
code, your custom stuff right
into the Interface
Builder canvas.
I think we really want
to help you guys get
to your vision faster
and to have some fun
while you do it, too.
Next is Adaptability.
And I love this about
our platforms.
It's all the places
that your apps can run.
Let's think about it.
We've got iPhone, iPad,
Portrait, Landscape, OS X, iOS,
and then throw in all
the languages, too.
Don't you love getting those
bugs that are like, hey,
there's this bug
in this language?
And I look at it and I'm like I
haven't heard of that language
and I just think that's
something that's great
about our platforms --
and as application developers
you're probably all well aware
of this.
Third is Power & Parity.
iOS and OS X have taken some
great steps toward each other
this year and I think
one of the places
that this is really illustrated
best is in Interface Builder.
And so we've got some tools
to help you seamlessly work
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And so we've got some tools
to help you seamlessly work
between both of our platforms
using really familiar
technologies and workflows.
So what's our plan for today?
How are we going to do this?
Well, my co-worker
started an app
and then he conveniently
left for vacation this week.
And so he didn't have
a chance to finish it.
So we're going to finish
it for him on stage.
And here's the ironic thing:
the app is actually about going
on vacation and sharing
your photos while you're
on vacation and rating those.
And so we're going to get to
look at my co-worker's photos
as he enjoys a drink
by the beach and Quinn
and I give this presentation.
So we have a list of sites here.
That little ring on the
outside is showing, kind of,
the popularity of that
particular destination.
Hawaii and London --
apparently great places to go --
I've never actually
been to either of those.
But New York -- apparently not
the most fun place to visit.
It must be that the pizza
isn't as good as Chicago.
[ Grumbling, cheering
and Applause ]
Now if I tap on one of these
sites it's going to slide over
and give me a little slideshow.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and give me a little slideshow.
I can rate my photos.
And then, here's
the iPad version,
and you might notice a few
little differences here.
So, for one, we have a
caption, and then, two,
that rating is kind of
[whisking sound] moved
over to the side there.
I'm also a photo nerd so I love
to know how you took your photo.
So if you tap that
little Details button,
you get a popover with some
location data and things
like the shutter
speed and f-stop.
So I think the best way to do
this is just to jump into a demo
and start making
this app awesome.
All right.
So I have my storyboard
here and I have the mockup
that I showed you earlier
from my designer, just as kind
of a reference, and
we'll use it as we go
through our presentation.
So in terms of strategy and
kind of starting your app:
the thing that I like
to do, personally,
is I like to get all my views
laid out first and then kind
of fill in the custom content.
So let's start by
adding constraints
for our table view cell here.
This box is going to our --
that circle tile view that
we'll fill in a little bit.
There's a couple of ways
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
There's a couple of ways
to add constraints
in Interface Builder.
One, I can just easily
control-drag to add, like,
a spacing constraint
for this view.
I can also use the
constraint popover here,
and this gives me some
additional features
for being able to pick
constants right on the fly,
pick a different object to
constrain to, things like that.
So now that our tile view
has got position and height,
well, what about width?
Well, we could add an explicit
width constraint but then
if I were to go change the
height of my table view cell,
I've got to go update it in
all these different spots.
So what I really want
to express is just
that this view should have the
same width as the same height.
And this is what's new since
last year, which is the ability
to create aspect ratios.
With the tile view now in
the spot that we want it,
let's work on these labels.
So I'm just going to grab
the label and just drag it
up in this spot, in
the position here.
And I can create
multiple constraints
at once using control-drag
by holding the shift
or the command key and
then just hitting return.
Now if I look back at my mockup,
you can see that the text
is really not centered
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
you can see that the text
is really not centered
with the tile view.
It's kind of like the
bottom of the text isn't
in the center this
particular tile view.
So now what we can do,
new since last year,
is we can actually go ahead
and change the attributes
involved in my constraint.
If I just open up the Attributes
Inspector for my constraint,
you can see now I can see the
Items and their attributes,
and I can just go ahead and
change this from Center Y
to Bottom, which is going to
move it down to the other side.
But one thing you'll notice is
that it didn't do
exactly what I expected.
So what's going on here?
Well, one of the things that I
notice is that I was thinking
about it in terms of the label,
not in terms of the view.
So another thing that our
Inspector gives us is the
ability to reverse the pieces
of the constraint in a way
that makes sense to you.
So let me undo that change.
And if I open this up again,
I can select Reverse First
and Second Item, and it
just flips the constraint.
This is mathematically
equivalent
to the other constraint but
I can express it in a way
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to the other constraint but
I can express it in a way
that makes sense to me.
And now I can say, okay,
the label's Bottom should be
at the View's Center Y.
Now one new field that you
might have noticed here is
the Multiplier.
So this is what enables
things like aspect ratios
and also proportional sizing
constraints and there's a couple
of different ways I can
insert a multiplier depending
on my situation.
So if I'm thinking about it
in terms of an aspect ratio,
I can do something like 1:4.
And you can see that now that
label's Bottom is in a ratio
of 1 to 4 with the
Center Y of my tile view.
But you know what?
Fractions might make more
sense to me so I'm going
to use a fraction instead.
So I can just type
in a fraction.
Or, of course, decimal numbers
are also applicable as well.
So our Title Label is
now in the right spot.
So let's do this Sub-Label.
So I can just drag
this into position.
And I'm just going to
do two more constraints
to get my views all laid out.
And I can show this by
resizing my Table View.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And I can show this by
resizing my Table View.
Now, one of the things
I love about getting
to show Xcode is giving you
guys a few tips and tricks
for being even more
productive in Xcode.
So this is going to
be Pro Tip Number 1.
If I hold shift when
I right-click
in the canvas it will give
me a menu of everything
under the mouse at the
point that I clicked.
So if I want to quickly
get to my Table View cell,
I just do that and select
it and now I'm ready to go.
If I resize my Table View cell,
you can see those constraints,
they're doing exactly
what I want.
I'm going to go ahead
and undo that change.
All right.
So, with our views in place,
we're ready to start
filling in that custom view.
And you've already seen our
Custom Views feature showed a
couple of different times.
What I'm going to
do now is I'm going
to show you the steps necessary
to have your content showing
up Interface Building from
start to finish, and show you,
I mean really, how easy it is.
The first thing we need to do,
Step 1 of 4, is we're going
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
The first thing we need to do,
Step 1 of 4, is we're going
to create a custom framework.
Frameworks are in OS X and
are new in iOS with iOS 8.
So I'm going to jump to
my Project Editor here.
I have my list of targets, and
I'm going to add a new target.
We want a Cocoa Touch framework.
So I'm going to call
this SiteRateKit.
(The name of our
app is SiteRate.)
And I'm choosing to embed
this in my iOS application.
It's going to do
two things: one,
it's going to link
my application
against this framework,
and; two,
when the application
builds, it's going to copy
that framework into
the app bundle.
So let's go ahead and
create that framework.
And that's it.
I have a custom framework
and it's all ready for me.
Now Step Number 2 in
getting your content to show
up in Interface Builder
is to create a subclass
of UIView (or NSView
if you're on the Mac).
So I can just right-click on
my group here, choose New File.
I want a Cocoa Touch class.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And I'm going to call
this SiteTileView.
Subclass UIView.
And we're going to use
Swift as our language.
I just want to make sure this
is added to the right target.
You want to make sure to add
it to your framework target.
And now our class is created.
So two steps down already.
The third step is to
tell Interface Builder
that this class can
display custom content
in Interface Builder.
And I can do that by marking
the class as @IBDesignable.
If I'm in Objective-C, the
attribute just looks like that.
So, Step 3 is done.
Our class is Designable,
our framework is created.
And the final step is to
simply tell Interface Builder
that an instance of a view
in my storyboard should
actually be this class.
So I'm going to go
back to the storyboard,
just using the recent
files here.
And let me go ahead and
select my tile view.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And let me go ahead and
select my tile view.
I'm going to open the
Identity Inspector
and now I can just type
in that tile view class
that I just created.
Interface Builder will
auto-complete it for me.
And now that's everything
that I have to do
to get my content showing
up in Interface Builder.
It's super, super easy.
Now, of course, nothing
is showing up
yet because we haven't
written any code,
but we're going to get there.
So, speaking of which,
let's actually now go ahead
and create some code
for our view.
So I want to show the code
for my view side-by-side
with my storyboard,
and that's really easy.
To open my class I'm going
to show you another
Xcode Pro Tip: Number 2.
If I option-click this
file, many of you know
that it will open in a new
assistant or in a new tab,
based upon how your
preferences are set.
But if I hold option-shift
and click,
I get a little chooser view.
And this chooser allows
me to pick the destination
of where I want this
file to open.
I can target a new split,
a new tab, a new window,
I can even target splits in
tabs that aren't even open.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I can even target splits in
tabs that aren't even open.
So, very, very flexible to get
to where I want to
open this file.
I'm just going to create it
in a new split side-by-side
with my storyboard.
All right.
So, there's a couple
different ways
that you can create
your custom views.
And the way that we're going
to do that today is we're going
to create our custom
view by composing it
of smaller components.
And these components are
either subviews like UILabel,
UIImageView or layers.
And we're going to
use layers today.
If I were to implement
drawRect, that's not going
to get us the best performance;
whereas, using sublayers
and subviews is going to get
us really good performance.
So I can just go ahead
and delete this code here.
And we're going to start
creating our view (if we go back
to our mockup here) by working
on these rings on the outside.
So I'm going to start with
this grey ring and then fill it
in with a colored one.
So let's create a
new shape layer
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So let's create a
new shape layer
on this, set it as a property.
And you can see it's giving
me an error because I need
to import the module
that contains the core
animation classes.
And I want to create this thing.
A really convenient
place to create this is
in an override of
layout sub-views.
First I want to call
super which will make sure
that all my subviews
have the right size.
And then, if I haven't
created the ring layer yet...
I'm going to go ahead
and create one,
add it to the layer of my view.
And then, of course,
we want to make sure
that we position it
in the right place.
So now we have a layer, let's do
something interesting with it.
I'm going to close
the utility area
to give myself a
little bit more space.
So let's create a Bézier
path and we're just going
to make this be a circle.
And then let's set this as
the shape of my shape layer.
And there, Interface Builder
is showing me the result
of my code so far.
[ Applause ]
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
[ Applause ]
Responds SUPER-fast,
which is just great.
So now I don't really want
a solid circle, right?
We want to create a ring.
And so CAShapeLayer has
a feature that allows me
to stroke the outside
of the path.
And so I'm going to go ahead
and turn off the fill color
to set a line width and set
the stroke color to black.
Now because my content
is showing live
in Interface Builder, I can see
that I've already
made a mistake.
For those of you
familiar with BezierPath,
you'll know that when
you have a stroke,
half of it draws
outside the path and half
of it inside the path.
So, actually, I want to inset my
path by half of the linewidth.
Now I know that I'm going
to use my linewidth a lot,
so let's create a
new property for it.
And now I can inset my
rectangle by that amount
and I'll make sure that
I use it in both spots.
And now my shape is
looking much better.
So the last thing we want to do
is we want to fill it in with
that color that our Designer
gave us, so we'll fill that in.
And, wow, that looks
really, really light.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And, wow, that looks
really, really light.
Hmm. I'm going to
change this to 0.3.
Designers aren't always right.
So now that my ring
layer -- [applause] --
[laughs] I love all
of our designers.
Now that our ring layer for
the background's looking pretty
good, let's fill it
in with some color.
I'm just going to do the
exact same thing, pretty much.
The only difference
I'm going to do
with this other ring layer is
I'm just going to rotate it
by 90 degrees so that when we
fill in our rating it's going
to come from the top of the
circle and not out of the side.
So I want to drive my shape
layer now by an actual rating.
So let's create a new
property which is the rating.
And now we want to actually
update our layer based upon this
rating, so I'm going to use
a feature of CAShapeLayer
that allows me to set the, kind
of, the progress of the stroke.
And I'm going to do it in a
new method, because I'm going
to call this row in a
bunch of different spots.
So one of these spots that
I'm going to call this from is
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So one of these spots that
I'm going to call this from is
from changing the rating itself.
It couldn't be easier now
to react to property changes
with Swift's new
Property Observers.
So all I have to do is just say
that when this rating did change
I can just go ahead and call
that method that
updates my shape layer.
And I'm also going to call
it inside of here just
in case we haven't actually
changed those properties yet.
And now my shape layer is
looking exactly how I want it,
so far.
Now it's really common when
you're creating different types
of custom views that you want to
have properties that you expose
that people can change,
either for your code or even
within Interface Builder.
And Interface Builder
makes that really easy
with a new feature
called Inspectables.
So if I go up to my
rating property here
and mark it as IBInspectable...
This is a flag for
Interface Builder
that says, "Hey, this property?
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that says, "Hey, this property?
I want you to show it in
Interface Builder" just
like all the other properties
that you edit on your views.
So if I jump back to Xcode
and I open the Inspector,
you can see that that rating
is showing up and I can edit it
and it reflects instantly
in the canvas.
[ Applause ]
So you might be wondering, well,
what can I use with
Inspectables?
You can use all kinds
of different types
for Inspectables.
Now the way that
Inspectables works is
that you might be
wondering "well,
where does all the
data get stored?"
Inspectables takes advantage
of the user-defined runtime
attributes that we've had
for a couple of releases
of Interface Builder.
You can see that the rating that
I just set is showing up here.
Now it's important that we
are using user-defined runtime
attributes for Inspectables
because it means
that you don't have
to worry about where
to store this data
and how to encode it.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to store this data
and how to encode it.
We take care of all
of that for you
at design time and at runtime.
The different types
that I can use
for Inspectables are
anything supported
by user-defined runtime
attributes: Booleans, strings,
numbers, values like points and
sizes and rects and even images,
which is new this year.
Love it. So Inspectables
I think are great
for exposing properties of
your views that you can edit.
But I think it's
also really helpful
for helping you develop
your views.
So there's two ways
that I see this.
The first thing is it helps
you just validate the changes
that you're making, especially
as you're experimenting
with new types of things.
So I want to change the color
of my rating based upon
how good that rating is.
Red means "you better catch up,"
and green might be "well done!"
So let's go ahead
and change the color
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So let's go ahead
and change the color
of our stroke based
upon that rating.
And I'm using a new
switch statement
in Swift to accomplish this.
And now you can see
that Interface Builder
is doing the right thing
in terms of the color.
Now I'm going to switch
back to Interface Builder
so I can edit the Inspectable.
And I'm going to show you
Xcode Pro Trip Number 3.
I like to navigate sometimes --
a lot of times --
without the mouse.
And I can jump around within
Xcode and put the focus
in different editors
using command-J.
If I hit command-J it gives me
a little chooser and I can pick
which editor I want
to have focused.
So in this case I want
to jump-focus back
to the Interface Builder editor.
So I can just go ahead
and hit command-J.
It picks the primary;
hit return.
And now you can see I'm
seeing my inspectors
for Interface Builder.
I can jump to the attributes
inspector with command-option-4.
And now that field's in focus
and I can try out our colors.
And everything looks to
be behaving as expected.
Now the next place that I
can use Inspectables in terms
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Now the next place that I
can use Inspectables in terms
of playing with my views is
also in just experimenting
with different types of values.
So I haven't decided
yet on my line width.
10 might work, or it might
not be the right thing.
So let's mark that
as Inspectable.
I'm going to jump back
to Interface Builder
using command-J.
That language is showing up.
And let's try a new value: 12.
Whoa, that is pretty thick.
So let's just, you know,
come back down here.
5's a little small.
What about 6?
Yeah, 6 looks pretty good to me.
So it's very, very
easy to experiment
with your custom
views when using them
with an Interface Builder.
Now I'm also going to show you
just how live these views are.
I'm going to go ahead and
resize my table view again.
And you can see,
as I'm resizing it,
it's just perfectly
redrawing my view.
It's interacting with it just
like any other view that's
inside of Interface Builder.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
like any other view that's
inside of Interface Builder.
Let me go ahead and
undo that change.
Okay. So our rings are
looking pretty good.
Let's go ahead and
fill in that image.
So I'm going to create a
new layer for my image.
I'm also going to declare
a property that I can set
for my code to update
that image.
Now, I want to put an image in
there, and so let's go ahead
and set that on our layer.
I'm going to come back down
to our layer properties here.
And, actually, I don't think
I want to create this inside
of our property, so let's
actually go ahead and undo that,
and let's create
the layer first.
And I'm going to do that
inside of our layout subviews.
That's looking a little better.
That's a better place to do it.
But let's update it down
here in our layer properties.
So you can see Interface
Builder is --
all I'm doing is I'm
just I'm drawing a square
and then I'm drawing a
circle and masking it.
And now we can set the
image as the contents
of that square layer behind it.
So let's get an image
to set inside of here.
Now I don't want
to ship any images
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Now I don't want
to ship any images
with my actual framework
(the images
that I use for testing, right?)
because that would just
bloat the framework.
What I'd like to do is be able
to reference an image that's
in my project without actually
putting it in a target.
And Interface Builder provides
a great place to do this
and a great way to do this
through
prepareForInterfaceBuilder.
So this is a method
that gets called
after your views are initialized
inside of Interface Builder,
and allows me to do any
kind of design-time setup.
Again, this only gets
called at design-time.
Now I have some images in my
projects, some test images.
Let me show them to you
over here in this folder.
And these aren't in any target.
They're just some images
that my designers gave me
to help me test to make sure
that my app is doing
the right thing.
So I'm going to go and
reference one of these.
But I want to -- so, I
could pass a, you know,
an absolute path and
generate an image.
But I'm going to do it
in a way that's going
to make sense for
my entire team.
So Interface Builder will
actually pass the paths
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So Interface Builder will
actually pass the paths
to your projects through the
environment and allow you
to actually take advantage of
the resources in your project.
So let's go back here and
let's go ahead and look
at what that looks like.
So inside of our
environment there is an
"IB-PROJECT-SOURCE-DIRECTORIES"
string.
That's just a bunch of project
directories concatenated
with a colon.
And I can split those
up and go ahead
and actually get the strings.
So I only have one project path
so I'm just going to go ahead
and grab the first one and
I can get the path relative
to my project just by appending
that test image's --
and, that image name.
And then we can go ahead
and create the image.
And it should -- hmm.
It should show up
here any second.
Huh. Well, this isn't
exactly looking right to me.
I think I must have
missed something.
Wouldn't it be great if I
could just debug my view right
in the canvas?
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
in the canvas?
>> Yeah.
>> Well, with live
views you can.
So I'm going to set a
breakpoint on my image here.
Go back to Interface Builder
and select my tile view.
And from the Editor Menu
I can just select Debug
Selected Views.
And this is going to attach to
Interface Builder and allow me
to actually debug
my custom view just
like any other debug session.
So I can see here the -- it
looks like I'm getting inside
of here, so I'm getting
a project path.
Let's go ahead and step over and
let's see what that image is.
You can see the LDB is
automatically printing
out the fact that this
is an optional type
and that the optional type
actually has something in it.
So let's see what that image is.
And, yep, sure enough,
we got an image,
so what's going wrong here?
Well, let me put a breakpoint
where we actually set
our image contents.
And let's hit Continue.
And, oh, interesting.
That method never
actually gets called.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
That method never
actually gets called.
What I must be doing is
I must have forgotten
to actually update my image
property in my image layer
when the image property changes.
If I scroll up --
oh, yep, sure enough.
I forgot to use a property
observer to make sure
that my image layer was
going to get updated
when the image changed.
And there you go.
So Interface Builder provides
lots of different ways for you
to be able to design your
views using something
like prepareForInterfaceBuilder
in these IB Project
Source Directories:
you can see your custom
images, you can debug them...
but there's even
more you can do.
So let's go ahead and
close the debug area here.
I'm going to jump over to a
different View Controller now.
And we have this Rating View
which is showing us the number
of stars for our
particular image.
Now this Rating View
has an Inspectable.
It's called Star Rating.
And I'm going to go ahead
and change this to 3.5.
And when I zoom back
out and zoom in instead
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And when I zoom back
out and zoom in instead
on our rating layer,
you can see -- oh, yeah.
That label there is
overlapping our star.
Well, why is that?
Well, we have this explicit
width and height constraint
so that the Rating View
doesn't have a chance to grow it
at whatever size it is.
So let's just go ahead
and delete those.
We don't need them.
So, again, delete those.
And now Interface Builder
is helpfully telling me
that my view is ambiguous.
It doesn't have enough
constraints.
Now for those of you
familiar with Auto Layout,
you'll know that there's a
method called Intrinsic Content
Size which allows you to define
a size-to-fit-size for my view.
Well, I can take advantage
of that right inside
of Interface Builder.
If we go to our Rating View
Class, and I'm going to open
that using Open Quickly.
Site Rating View.
And I'm going to use
my little option-shift
to target the assistant here.
And we'll scroll to the bottom
of the file to add our new code.
So I've overwritten our
intrinsicContentSize method
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So I've overwritten our
intrinsicContentSize method
and now Interface
Builder is going
to recognize that
method is there.
It's going to call it just like
it normally would at runtime.
And now it's showing me that my
view can grow to fill the size
of the stars and the intrinsic
content size of my label,
and I can just put
it right into place.
And it's also telling me that my
view is now no longer ambiguous.
I'm all good to go.
It's executing my code and using
that intrinsicContentSize
override to figure
out which constraints
need to be there.
Now for those of you who
are "pixel perfectionists,"
you might realize that that
caption is actually 1 point off
from this label in
terms of being aligned.
I would like to be able
to align these two things
by their baseline but my
Rating View is a custom view
that has stuff inside of it.
Well, how do I align
it by the baseline?
Well, I can override another
method on UIView and NSView,
called viewForBaselineLayout.
I'm going to return the
label that's internal
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I'm going to return the
label that's internal
to my custom view.
And now Interface
Builder is showing me
that this view now has
a baseline running right
through the baseline of my label
and if I delete the centering
contraint on my caption,
I can just drag this
thing around
and you can see it snapping
right to the baseline
of that custom view that I
just created entirely in code.
[ Applause ]
Now I can go ahead
and finish this off
by baseline aligning
these to these two views.
So that's just a little look
into using live views and some
of the things that you can use
to make sure really cool views.
I'm really looking forward
to seeing what you guys do.
So, the four steps
that you need to do
to get your custom content
showing up in Interface Builder:
1, create a framework.
Why do you need to create a
framework in the first place?
The way that this feature works
is that when you define a class
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
The way that this feature works
is that when you define a class
as designable, Interface
Builder is going
to build your framework target.
It's going to launch
a Helper process.
It's going to dynamically
load your framework
into that Helper process
and then interact with it.
And this also helps keep you
from the mistakes that --
at least that I make
-- while writing code,
which is something like a crash.
That way you don't have to --
you can see what the error is
without having to
suffer from it.
Secondly, you create a
subclass of UIView either
with Objective-C or with Swift.
Third, you mark it
as Designable.
And I wanted to say a quick
note about Inspectable as well.
While Designable is a feature
of this Custom Views feature,
you can use Inspectables without
having a Designable class.
You can add Inspectables
to any of your classes
that you interact with
in Interface Builder,
and we'll show you those
properties in the Inspector.
And then, finally, you just
hook up your custom view
with the class that
you just created.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Live Views allows you to
do all kinds of things:
you can see your custom drawing,
you can have custom geometry
and interact with it...
One that I didn't show you
is you can also provide the
alignment rect insets that
are on both iOS and OS X.
You can debug your views
right in the canvas.
And you can also use several
mechanisms for interacting
with your code in design-time.
I showed you
prepareForInterfaceBuilder,
but another one is this
target conditional,
TARGET-INTERFACE-BUILDER.
And you can use this with
#if to either opt code
in or out of live views.
So, for example, you might have
some server connection code
that you don't want to run
when you're inside
of Interface Builder.
So you can just opt that out
using this Target Conditional.
I also showed you some new Auto
Layout features since last year.
Now what we want to do is want
to add iPhone Support
to our application.
My co-worker just had
time for iPad support.
And our goal is that we're going
to use a single storyboard
to do this.
and this is made possible
because of a feature
called Size Classes.
Size Classes is a feature of iOS
8 and Xcode 6 that allows you
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Size Classes is a feature of iOS
8 and Xcode 6 that allows you
to specify how your View
Controller and your UI adapt
as the available size for
your View Controller changes.
Let me tell you -- I'm going
to walk you through an example.
Let's say you start out
with some View Controller
with some size and it
grows to some new size.
What's important here
is not the point size
of your View Controller
either in the smaller
or bigger configuration.
What's important
is the magnitude
of the change, small versus big.
This magnitude is
called a Size Class.
A Size Class can have
one of two values.
Compact (think small) or
Regular (think bigger).
At any given time, a
View Controller is going
to have two Size Classes, one
horizontally and one vertically,
making the total number
of combinations four.
So let's look at a
concrete example.
So I have our UI here and
when we're in landscape
on the iPhone, I'd really like
that bottom bar to tighten
up a little bit, to make
more room for those images.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
up a little bit, to make
more room for those images.
So what we can do is
in the configurations
of our four configurations,
for whether that bar
or whether the View
Controller is
in a more compact vertical
environment, we can just set
that constant to 30 and in the
bigger ones we can set it to 52.
We're all good, right?
Well, kind of.
If you notice, I have to
specify the value twice.
And this is going to
make it really hard
to make edits in the future.
It's going to make it
hard to maintain my app
because every time I
make a change I've got
to make it in two places.
So Interface Builder
exposes a third value
in the Size Class called Any.
And Any is simply,
as its name suggests,
either of the size classes.
So I can say that I want that 30
to be for any horizontal class.
I don't care what the width is.
All I care is about the
height, which is compact.
What about this 52?
Well, I could also put
it in Any for regular,
but where I really want
to put it is in Any Any.
This is the default
configuration.
This says that it doesn't
matter which device
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
This says that it doesn't
matter which device
or which orientation or what the
size of my View controller is,
I want to use these values.
And this brings up a
really important strategy
as you're designing
your applications.
You want to do as much work
in Any Any as possible.
And then you just branch
out to those more specific
configurations as needed.
And this is going to make your
app much more maintainable
and much more adaptable.
Now this grid is going
to become really familiar
because this is actually
exactly how we expose switching
between the different
configurations inside of Xcode.
And let me show you
how that works.
All right.
So we're back in our
lovely storyboard here.
And the first thing
I'm going to do
in this storyboard is I'm
going to enable Size Classes.
So let me go ahead and open
up the Document Inspector here
and check Size Classes.
Now two things are
going to happen.
One, if your document
isn't using Auto Layout,
we're going to turn on
Auto Layout for you.
And them, secondly, it's going
to upgrade all of your segues
to the new Adaptive Segues.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to the new Adaptive Segues.
Now, I'm going to talk
about that in a little bit.
So we're going to
enable Size Classes
and immediately we're seeing
the result, the designing,
and this great, flexible,
adaptable environment.
Our View Controllers are showing
a square to help reinforce
that you're not designing for
any specific, particular device,
but rather for the particular
size or magnitude of size
of your View Controller.
So, the first thing that we
want to do is we want to take
that bar and make it a little
bit narrower or shorter
when our height is
a little narrower.
So I can just go ahead and put
the canvas into a configuration
that allows me to do that.
So this is the first thing with
Size Classes is transitioning
through the different
configurations.
It's really easy.
If I open up this control here
in the bottom of the canvas,
you can see it was that grid
that we were seeing earlier.
And this allows me to pick
which configuration I'm editing.
When I pick a configuration
to edit,
it's going to resize
the View Controllers
for that particular
configuration to reflect that.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
for that particular
configuration to reflect that.
And now, any edits
that I make inside
of this particular
configuration will be customized
for that configuration.
So let's go ahead and do
that now for the constant --
the height constant
-- on our bar.
So I'm going to go
ahead and select this.
Now I could double-click
to edit this constraint,
but instead what I'm
going to do is I'm going
to open the Size Inspector.
And you can see here all
the constraints for my bar.
Well, I really just want to see
the ones that are being defined
by my parent to kind of
position and size this.
I'm just going to filter the
constraints down to those.
And furthermore, I'm just going
to look at size constraints.
Then, to change the constant,
just click once, type in 30,
hit Return, and now
I've customized my bar
for Any, Compact.
[ Applause ]
You can see the result of that
if I switch back
to "Any Any" here.
And you can see that bar grew
back to that taller height.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And you can see that bar grew
back to that taller height.
So, really, really easy
to make customizations
between configurations.
Now the second thing about Size
Classes that I wanted to say is,
well, what's customizable
between configurations.
There are four things
that are customizable
between configurations.
One: I can change a
constraint constant.
Two: I can change a font.
Three: I can change whole
sets of constraints --
I can turn off an entire
set of constraints (say,
my Portrait constraints) and
turn on a whole other set (say,
my Landscape constraints).
And then, fourth, I can
also customize subviews,
turning them on and off.
And this is different
from hidden.
When a view is just hidden, it's
still participating in layout.
But when I uninstall the
constraint using the view using
Size Classes, it actually takes
it out of the View hierarchy
so I can have new
sets of constraints.
So let's see an example
of that now.
When I don't have a lot
of horizontal space,
I want to turn off this rating.
So I'm going to go ahead and put
the canvas into Compact width.
And I don't really
care what height it is.
It can, you know, be as tall
or short as it needs to be.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
It can, you know, be as tall
or short as it needs to be.
And you can see...
oh wow, yeah, that
looks pretty bad.
So let's go ahead and
turn that caption off.
When I want to turn
a subview off
in a configuration it's
really just as easy
as turning off the constraints
of that configuration
and then turning
the View off itself.
When I use the constraint
commands over in this menu,
they're going to apply, again,
for just this configuration.
So let's go ahead and just clear
the constraints for this View,
and now we can uninstall
it from this configuration.
I can do this using the
Inspector on a per-view instance
or a really quick
shortcut for getting
that done is just
command-delete.
And command-delete
will just turn it off
in this configuration.
Delete will delete it in
all of the configurations.
I also want to go ahead
and remove this constraint.
So I can just select the
constraint, command-delete,
and now I've turned it off.
And now I can add
new constraints
for just this configuration.
So I'd like to take
this Rating View
and align it horizontally
in my container.
And I'm going to use the
new -- or not the new --
just the existing
alignment popover here.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I'm going to choose Horizontal,
Center, and Container.
And I'm going to change one
of this Update Frame's values.
You might have been
wondering what this is.
This allows...
when you're adding
new constraints,
the values that you're
adding those constraints
for might not be
the actual values
that are currently
reflected in the canvas.
For example, I want to add
Center in my bottom bar
but my View currently isn't
centered in the bottom bar.
So I can tell Interface
Builder, hey,
when you add these constraints,
just go ahead and put the Views
in those new locations.
And that's what these
options allow me to do.
All Frames is just
-- it updates it
for the whole View Controller.
And "Items of New Constraints,"
this is helpful if you're
in the middle of doing a lot
of different constraint surgery
and you just want to
move one or two Views.
What I'm going to
do in this case,
I'm going to do all the
frames in my View Controller.
And you can see it adds that
constraint [whisking sound]
and it slides that
Rating View right on over.
And if we go back
to Any Any, voila.
We've customized our interface
across two different
configurations very,
very easily.
And let's see what this
looks like at runtime.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And let's see what this
looks like at runtime.
If I go ahead and
run my application...
There, it's showing up, and I
can rotate it, and you can see
that bar is automatically
adjusting.
And on iPhone, because
it's Compact,
you can see that that
caption isn't showing.
Now one thing I haven't
talked about or pointed out
yet is maybe something
that you guys are wondering
and you're saying, hey,
you had an iPad storyboard.
Wait a second.
I saw a Split View
Controller in there.
I saw that you had
a Replace Segue.
I saw that you had
a Popover Segue.
How is that working on iPhone?
With the new adaptive View
Controller API in iOS 8,
all the wonderful system
classes that you've come to know
and love work on
both iPad and iPhone.
And the way that it works is
that they adapt their
environment based upon
that available size.
So, for example, our
Split View Controller ,
instead of showing side-by-side
(because the environment is more
compact) it's actually
going to just push my detail
onto my master when I'm
in a more compact
environment like an iPhone.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
in a more compact
environment like an iPhone.
Similarly, with my
Popover Segue,
instead of being a popover
on iPhone, it's been turned
into a modal without
me writing any code.
And this has to do with those
new Adaptive Segue types.
So let's take a look
at those now.
If I select this
Popover Segue here and go
over to the Attributes
Inspector, you can see it's one
of the new Present
As Popover Segues.
And this is one of the
new Adaptive Segues.
Let's take a look at what
other Adaptive Segues we have.
Show is a replacement,
for example, for Push.
And what Show in Show Detail
does is it looks at the context
that you're in to
decide what to do.
So, for example, a Split
View Controller in iPad:
it's going to actually
replace the Detail
if you have a Show Detail.
But on iPhone, it's
going to push
that Detail aside
on to the Master.
Now what's really
cool about this is
that this is accomplished
by using two new UIView
Controller Selectors,
Show View Controller and
Show Detail View Controller.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Show View Controller and
Show Detail View Controller.
You can override these
for custom containers
and then you can design those
containers in Interface Builder
to set up your Segues and it's
just going to work at runtime.
The other two types are Present
Modally and Present As Popover.
And these are using the Present
View Controller API instead
of Present Modal View
Controller which allows you
to take advantage of the new
Presentation Controller API
which is a new object when you
use Present View Controller.
And you can do things like make
sure that the custom transitions
that you have are
all coordinated along
with the animations which
is really, really great.
So we're going to use
Present As Popover
which will allow our
Presentation View Controller
to automatically adapt.
Now if I go back to
my storyboard here,
you can see there's no
button for closing this.
And so, if I had time, I
could go ahead and add this,
and you're welcome to
come down to the labs
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and you're welcome to
come down to the labs
and I'll show you
how to do this.
But with the new Adaptive
View Controller API,
what I can do is I can
take advantage of some
of the overrides in delicate
methods to do things like,
for example in this
case, I can say,
when this Popover Segue
gets fired, go ahead
and wrap the View Control
that you're presenting
in a Navigation Controller,
add a bar item, and then just
on iPhone it's going to show
me a Done button that I can use
to close that Modal
View Controller.
But when on iPad, and it's
showing as a Popover, well,
I don't need that,
so it won't show it.
Very, very cool for being
able to create great apps
between both iPhone and iPad.
So we just talked
about Size Classes.
And, again, Size Classes is
a really great technology
that will make it
really easy for you guys
to create these experiences
both for iPhone and iPad all
within the same storyboard.
And I also talked to you about
the new Adaptive Segue Types.
And we really want you guys
to use these new Adaptive
Segue Types because it's going
to make your application
be able to (hence,
as their name suggests)
adapt very easily
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
as their name suggests)
adapt very easily
between the different types
of environments that
it might run in.
I also pointed out that you
can create custom containers
and use those Show and Show
Detail View Controller methods
to customize exactly how those
View Controllers are going
to get presented.
Maybe you have a Sliding
View Controller or something
like that, and you
can build all that now
within Interface Builder.
What I want to do now is have
my colleague, Quinn, come up.
He's going to show you
even more stuff that's new
in Interface Builder
and hopefully tell some
better jokes than I did.
Quinn?
[ Applause ]
>> Thank you.
Hi. Thank you, Kevin.
So my name is Quinn Taylor.
I'm also an Engineer on
the Interface Builder Team.
This is such a fantastic team
and I hope you can feel how
much hard work we've done
to bring to you guys.
We love these new features
and I can't wait to tell you
about a few more of them.
So, first off, I want to talk
to you about Asset Catalogs.
We introduced Asset Catalogs
last year with Xcode 5.
And they're a fantastic way
to manage resources
inside your application,
both for iOS and for OS X.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
both for iOS and for OS X.
And one of the first new
features that we've added
to Asset Catalogs in Xcode 6
is support for Size Classes.
As Kevin has just been
demonstrating to you,
you can easily adapt your
user interface for Compact
or Regular height or width.
And now notice that we have
new fields in the Inspector
when you selected an image
in your Asset Catalog
that allow you to
customize the same way.
Now if you select
one of these --
for example, we'll
customize on Compact width.
You'll see that new rows
appear that allow me
to optionally specify new
images that will be used if I'm
in a Compact width scenario.
So, any images that you
don't actually specify
for a specific configuration
will be inherited
from a less specific
configuration,
just as Kevin was talking
about with Any Any.
So this is a fantastic feature
to allow you to customize.
Second, Alignment support.
So, there may be occasions
where you have an image provided
to you by a designer
that doesn't fill the
entire space of the image.
For example, it may have a
glow effect, some other padding
that causes it to be inset.
And now you can also show
that information and convey
that inside of Interface
Builder and your Asset Catalogs.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that inside of Interface
Builder and your Asset Catalogs.
And this will correspond to
the alignmentRect properties
on either NSImage or UIImage
when you can specify alignments
from any of the four edges.
This is fantastic.
And next is Image Formats.
So when we launched the
Asset Catalogs last year,
we supported PNG images.
So we've heard your requests.
The first thing we
added is support
for JPEG images [applause].
>> Whoo.
>> Some of you love
your JPEG images.
This can be really handy
when you have resources
that might be large and compress
better with JPEG than they do
with PNG, so you can save space
in your application,
and that's great.
Second is PDF vector images,
and these are great as well.
So this is -- let me tell
you, this is a fantastic way
to specify an image that
will scale automatically
to your different
scales and resolutions.
When you're building an
Asset Catalog for iOS,
those vector images
we've rasterized
to the correct resolutions
and scales at build time.
On OS X, however, they're
preserved at runtime
and they'll even appear
at scale for printing
which is a really cool bonus.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
which is a really cool bonus.
And you're also able to mix and
match bitmap and vector images
for any particular asset.
And last is support
for template images.
Matthew mentioned
this a bit on Monday.
Template images allow an
image to be treated kind
of as a stencil in
your application
so you get kind of
an outline effect.
And traditionally this is done
by detecting whether the
file name ends in "Template."
And now we give you the ability
to override this
default behavior directly
in Interface Builder
in your Asset Catalogs.
So, that's it for
Asset Catalogs.
Next, you've seen
a few new classes.
I'm going to talk
about OS X for minute.
NSVisualEffectView is a brand
new class in OS X Yosemite.
You've seen it pervasively
throughout the system behind
Notification Center,
behind your menus
and behind your source
lists and so on.
You'll see effects like
blurring, translucency,
vibrancy, punch-through
effects, and masking.
And you can bring
these same effects
to your own applications.
VisualEffectView is supported
completely in Interface Builder.
And you can have your own
custom views participate
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And you can have your own
custom views participate
in vibrancy effects
by overriding the allowsVibrancy
method on NSView or UIView.
For much more information
about how to integrate this,
definitely check out this
session on Adopting New Features
of the UI in Yosemite on video.
Next, you've heard word
of a new System Font.
Andrea's talked about this.
The great news is for you,
you don't have to do anything.
Use the system font;
it's going to work.
AppKit and Xcode will
take care of you,
so you don't have any
worries on that front.
Speaking of fonts,
iOS Custom Fonts...
[applause] [Laughs]
You're already excited.
I share your enthusiasm.
For a couple of releases
now, you've been able
to use Custom Fonts in
your iOS Applications.
You can put them in your project
and copy them to your bundle.
And now we're adding
support for being able
to pick those fonts
directly in Interface Builder
and have them show up in
the canvas live for you.
So here I've chosen this font
that looked pretty cool in OS X,
brought it over, and I can
see, I can ingest the metrics
and make sure that it looks
just right without having
to run my application
over and over.
This is a fantastic timesaver.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
All right.
So pictures are worth
a thousand words.
I feel that demos are
worth a thousand pictures.
You know, I'm going to,
I'm going to get in a --
step on Kevin's toes
just a little bit here
with this custom font.
So I've got my iOS storyboard
that he's been working on.
And, you know, this
looks fantastic.
He's done such an awesome job.
But, you know, the thing
is, this is a vacation app.
And to make it, you know,
make it a little bit more fun
and vacationey, maybe we
just need a custom font.
Now I've actually snuck a
font into his project here.
So I'm going to go right over to
the Font Picker, and you'll see
that it shows right up in
here in Interface Builder,
and I can pick my font.
It shows right up.
Now that looks a
little bit smaller
than what I was expecting,
so maybe I can bump
up the size just a
little bit to 36.
That looks pretty good.
And I could do the same thing
here for my subtitle, my label.
Hmm. Bump the size up to
-- 20 looks pretty good.
Okay. And now, since those fonts
are just a little bit different
in metrics, I can
update those frames.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
in metrics, I can
update those frames.
Okay. So that looks fantastic.
So now I can see right on
the canvas what it's going
to look like at runtime.
I've got that information
available to me.
And it's going to
save a lot of time
when you're designing
your iOS Applications.
All right.
So now I'm going to jump over
to what I've been working
on while Kevin was onstage.
I was working on the
Mac version of this.
He's a pretty quick worker, so I
was trying to catch up with him.
I've kind of copied some of
his work here, you can see.
So we've got a very
similar layout.
And what you'll notice is
I'm using OS X Storyboards
which is a new feature
in OS X Yosemite.
And, if you're familiar
with storyboards,
this will be immediately
comfortable to you.
We're building up our
interface using Scenes connected
with Segues.
And we're showing our
organization directly here
in the canvas, all the
connections between them,
and how my application's
going to flow.
And this can be an
incredibly convenient way
to see how your application
works.
You'll notice that my main menu
is actually still present here
and I can edit that just
as I would in .XIB Files.
You can actually do your
entire application development
within an OS X Storyboard.
So, in addition to just being
familiar to iOS developers,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, in addition to just being
familiar to iOS developers,
there's some great
features within storyboards
that actually make your life a
lot easier, you Mac developers.
For example, presenting
a Popover
or a Sheet can be
rather difficult.
And you have to write code
to get it to start and end.
And this is just as simple
as creating a Segue
to present a Popover.
You have a scene
that has your view,
and voila, it's right there.
It's a really fast way to do it.
In addition, managing
Tab and Split Views.
Here, in fact, we have
a Split View Controller.
Now NSSplitViewController
and NSTabViewController
are also new in Yosemite.
And you can use those in
either XIBs or Storyboards.
So I've configured a
Split View Controller here
with two Split View items
with my Master and my Detail,
similar as what I
would do on iPad.
And you can see I can use
the same type of things here.
I've got, in fact,
an NSVisualEffectView
down at the bottom.
And it just works.
So let me show you,
running this application,
on Mac using storyboards.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Okay.
So here's my application.
I've got a nice looking
source list
and I can click between them.
I've got my photos,
I've got my rating
at the bottom, I've
got my captions.
And I've done it
with Storyboards.
I can see all of it in one place
and it's incredibly convenient.
So I hope you guys will check
this out as you're working
on Yosemite and higher.
These can be deployed only
to Yosemite and above.
But they are a fantastic way
for new application development
to speed up your development.
All right.
Next I want to talk
to you a little bit
about gesture recognizers.
You're probably also
familiar with these from iOS.
Now in Yosemite we've added
five gesture recognizers
and we have support for them
in Interface Builder as well.
So let's say that I want to
add a gesture recognizer.
I'll filter an Object Library.
You can see these
five that pop up.
Let's say that I want
to go ahead and put
in a magnification
gesture recognizer.
I want to do some sort of
pinch-to-zoom kind of action.
So it's as simple as dragging
it from the Object Library
onto the view where you want
to recognize the events.
Drop it right there.
You'll see it appears
in my Document Outline
here on the left.
Okay? Now all I have
to do is connect it
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Okay? Now all I have
to do is connect it
up to the source code.
So I have my View
Controller here.
I'm going to Option-Click
on my Site View Controller
to open it in a split.
And let me close
this area for now.
I can use the ConnectToSource
feature
within Interface Builder.
I can control-click and drag
from my magnification
gesture recognizer directly
into my source code and
have it create an outlet
or an action for me.
In this case, I want to
create an action method
that my gesture recognizer
will invoke when events happen.
So I'm going to select
Action and try
to be a little clever here.
I like to use fun names
sometimes, so I'm going
to call this "Biggify."
Add some mystique and
excitement to the code.
All right.
So now you can see I've got
this connection right here
to the action method, right,
for my gesture recognizer.
And when I run this, this
method's going to be invoked
and the code that I write here
will be fired without me having
to do any event detection
myself.
It's a fantastically
convenient way
to develop your applications.
Okay. You know I'm already kind
of starting to regret the choice
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Okay. You know I'm already kind
of starting to regret the choice
of that selector
name, "Biggify."
It's a -- you know, when
my co-worker comes back
from vacation -- look
at how happy he is there
on vacation while we're at WWDC.
And you know, he's not
going to be too pleased
to find a name like "Biggify."
So we're going to use the
new Find and Replace feature.
And I'm going to use
command-option-shift-F to bring
up my Find Navigator in
the Find and Replace mode.
So I'm going to get
that horrible selector
name out of here.
I'm going to search
for "Biggify" and...
something more reasonable,
like "Zoom."
And as I hit return, you'll see
that it detects now instances
of that selector,
both in my source code
and in my Interface
Builder documents.
They're a fantastic timesaver.
[ Applause ]
So I can select both of these
instances and replace them.
Oh, see -- Snapshots
is trying to get
in on my photo application here.
It wants to take a picture, too.
So we're going to
actually just replace that.
And you can see I've
got Zoom right here
for my Magnification
Gesture Recognizer.
The action has been
replaced as Zoom.
I don't have to destroy
my connection,
change my selector name, and
recreate all those connections
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
change my selector name, and
recreate all those connections
that may call into it.
So it's a fantastic timesaver
for Find and Replace.
In fact, Find and Replace also
works within Document Find.
So, with command-F, I can
bring it up right inside
of my document here and I can
search for all sorts of things.
You can find strings
that appear in text.
If I look for a label, I
can find those as well.
And it will highlight for
me where it may appear
in a Selector Name, where
it may appear in text
in a string, and so on.
For example, let's look for --
another thing that you can use,
to find for (unexpectedly
convenient) is to jump
between parts of your
view, if you like.
So, for example, I have
my Site View Control
and I have a list you can draw.
So I can type List, and
it's going to show me --
here's my Site List
Table View Controller.
This can be incredibly handy
when you have a large storyboard
and you have your scenes named
appropriately, and you can jump
between them with Find
right in the document.
So this is a fantastic
timesaver as well.
So the last thing that
I'd like to demonstrate
for you is a little bit of how
Interface Builder participates
in your localization
workflow to help improve that.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
in your localization
workflow to help improve that.
So I'm going to open my
Assistant Editor again,
and I'm going to
close my utility area.
Now I want to bring
up my Preview.
And you'll see that
my Selected View shows
up in the Preview
on the right side.
Now if I have localizations
already,
I can use those to preview.
Kevin and I have
only been working
on this for a little bit.
But we're pretty sure this app
is going to take off worldwide
and we're going to have
all sorts of localizations.
For now, all we have is English.
But even when you don't
have any translations,
you'll see this entry in there,
Double Length Pseudo-Language.
So I can test this and see:
"How is my user interface
going to react?
Are my auto-layout
constraints set
up correctly to help
those views?"
You can go ahead and clap, yeah.
That's fantastic.
[ Applause ]
I can see without running my
application how my interface is
going to react.
And I can see that as I
select from view to view.
All my strings will be doubled
and I can easily see that.
Once you have translations, you
can easily plug those in as well
and you can test those in
Interface Builder at design time
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and you can test those in
Interface Builder at design time
which is a fantastic timesaver.
All right.
So, you've seen some of
the great new features
that we've been working hard
to bring to you this year
in Interface Builder
and Xcode 6.
Again, revisiting these three
big themes: First is Liveness,
that more of your
views and your content
and your application are live
in the IB design
canvas than ever before.
There's more power for
you to iterate quickly
and avoid the costly build
and run and debug loops.
Second is Adaptability
and greater dynamism.
Being able to adapt to
changes in configuration
where your view can appear.
And third is Power & Parity.
Great new features
in OS X and iOS
and within Interface
Builder itself
to help you work more quickly
and efficiently than
ever before.
Any questions you have
should be directed
to our Developer
Evangelist, Dave Delong.
We have great documentation
online available.
There are quite a few related
sessions that will be fantastic
for deeper dives into
the subject matter
that you can catch on video.
Thank you so much and enjoy
the rest of the conference.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Thank you so much and enjoy
the rest of the conference.
[ Applause ]