Transcript
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
[Applause]
>> KYLE SLUDER: Good morning!
Happy Thursday to everybody.
Congratulations on making it
to a 9:00 a.m. session
this late in the week.
[Laughter]
>> KYLE SLUDER: I was
in your seats last year.
I know exactly how
difficult that can be.
Today we're going to talk
about some improvements
that we've made to storyboards.
Just to help everybody warm-up
and get ready for the day,
I'm going to do a
quick exercise here.
How many people here
have shipped an app
that uses storyboards?
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that uses storyboards?
That is a very good number.
How many people here have
maybe tried to use storyboards
or thought about using
storyboards and either they
or their team decided that this
isn't the way we want do this?
Maybe not for now.
Okay. How many people
here have never used the
storyboard before?
Wow, this is a very
experienced crowd.
All right.
We're going to focus on
three main areas today:
First we're going to talk about
a new feature that we've added
to help you organize
your storyboards
and keep them manageable
and then we're going to talk
about ways that you can
customize the standard segueway
ways that we've provided
for you in Interface Builder
and finally we're going to talk
about what might be a little
bit more of an advanced feature,
unwind segueway ways and how we
have improved them in relation
to the custom container view
controllers that you use in iOS.
So let's get started.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So let's get started.
We have a really simple
demo application here.
It is just a collection
view that displays a bunch
of photos inside of
navigation controller.
If I tap one of those
photos, it comes in onscreen.
Then I can tap that back button
in the upper-left
corner and it goes away.
The three components of that
user interface correspond
to three view controller
instances at runtime.
If I were to diagram
this application
out on paper I might
do something like this.
It might represent those
view controllers as boxes
and then draw lines between
them to describe the flow
through my application.
That's the kind of information
that a storyboard captures
for you and let's
you use at runtime.
There's a bit of
specialized terminology
with regard to storyboards.
Those boxes that have been
turned into circles here,
we call those scenes and
they act as templates
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
we call those scenes and
they act as templates
for the view controllers
that actually make
up your user interface
at runtime.
Those lines we call segueways,
and there are a couple
of different kinds of segueways.
That relationship --
that segueway between
the navigation controller
and the collection view
controller is a kind
of segueway called a
relationship segueway.
Specifically it states that that
collection view controller is
at the root of the
navigation stack managed
by that navigation controller.
Another kind of segueway
is a triggered segueway,
this one specificallys says
that when I tap on a cell
in a collection view I want
to show my photo view controller
using the semantics defined
by the show view
controller method.
When we actually
put this altogether
in a storyboard file we
can give things identifiers
and then we set that up
in Interface Builder --
in Xcode as our main
interface file for our project
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and we run the application.
The first thing that happens,
is that we instantiate a
navigation controller based
on what's in the initial
scene in our storyboard
and then we see that there
is a relationship defined
on that navigation controller.
So we instantiate the view
controller at the other end
of that segueway and then we
establish the relationship
that is defined by
that segueway,
that root of the
navigation stack.
Later on as the user is using
our application they tap
on a collection view cell
which performs that segueway
that we have labeled
show pic here,
that's that show
segueway from before.
We instantiate the view
controller at the other end
of that segueway and we
establish the relationship,
we perform that action
that the segueway defines.
As you're designing
your application,
you're implementing your
application your interfaces get
more complicated and
so do your storyboards.
Eventually in order to
keep things manageable,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Eventually in order to
keep things manageable,
just like you split your source
code into multiple files,
you split your storyboards
into multiple files,
but we can't draw a segueway
across a file boundary.
We can fall back to code, we
can instantiate an instance
of that secondary storyboard,
and we can instantiate view
controllers based on the scenes
in that storyboard, or
we have lost the ability
to visualize the connection
between the scenes.
What we really want to do is
we want to get that arrow back.
That's what we have
done for you in Xcode 7
with a new feature we call
Storyboard References.
[Applause]
>> KYLE SLUDER: So just so
you know, you're all have
to applaud again for Tony
because he actually did most
of the work on implementing
this.
[Laughter]
>> KYLE SLUDER: A
storyboard reference stands
in for another scene and
that scene can actually be
in to the same storyboard
or in another storyboard.
Just like any scene, it can be
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Just like any scene, it can be
at the destination
end of any segueway.
Really that's all there is
to say about that so I'd
like to ask Tony up, show you
how easy it is with Xcode 7
to organize your
storyboards for OS X 10.11,
iOS 9 and watchOS using Xcode 7.
[Applause]
>> TONY RICCIARDI:
Thank you, Kyle.
Good Morning, my name is Tony
and I work on Interface Builder.
In this (unintelligible),
I'll show you our new feature,
called Storyboard References,
but before we get started let me
show you the app we're building.
This is an app to
help you organize
and plan events for a road trip.
I implemented the UI for this
app using a custom container
view controller which
manages four tabs.
Each of these tabs
is implemented
with its own UI navigation
controller and you can open
up a tab by tapping
on its navigation bar.
This first tab shows a
table of upcoming events.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
This first tab shows a
table of upcoming events.
This tab shows a
journal of past events.
Here we have a map
of upcoming stops.
Finally, we have a
collection of photos
that we have taken on our trip.
You can tap on a photo cell to
get a larger view of the photo
and you can tap on
this bar button item
to get a menu of
possible actions.
Let's take a look at the
main storyboard for my app.
Up here in the top left I
have my custom container view
controller and that
container is connected to each
of its four child navigation
controllers using an
embed segueway.
An embed segueway allows you
to embed a child view
controller inside of a parent.
As you can see, over time
this storyboard has gotten
pretty large.
And so what I want to
do today is break it
up into smaller pieces.
If we take a look at the bottom
of my storyboard you can see
that I have the three view
controllers for my photos tab.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that I have the three view
controllers for my photos tab.
These view controllers are
mostly independent of the rest
of the scenes in my storyboard.
And so it would make
sense to pull them
out into their own file.
To do that, I'm going to select
these view controllers and head
up to the editor menu and
choose refactor to storyboard.
I'm going to call the new
file photos.storyboard.
When I do that, Xcode
generates a new storyboard file,
pulls those view controllers
out of my main storyboard
and puts them in the new file.
What happened back in
the main storyboard file?
Let's use the back button.
Down here where we used
to see those three view
controllers we now have a
storyboard reference.
Whenever you refactor
scenes from a storyboard
and the scenes have incoming
segueways, Xcode is going
to take those segueways,
generate a storyboard reference
and reroute the segueways
to the reference.
At runtime when this
segueway executes,
it is going to instantiate
the initial view controller
out of my photo storyboard and
use that as its destination.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
out of my photo storyboard and
use that as its destination.
If I double-click on this
reference Xcode takes me
to that storyboard and
shows me the view controller
I'm referencing.
Which in this case is
the initial navigation...
the initial view
controller of the storyboard.
That's one way to
use this feature.
You can take a large
storyboard file
and refactor it into
smaller pieces.
Another way you can use this
feature is to create segueways
to view controllers that
already exist in separate files.
I'm going to create a new
segueway now and I want
that segueway to be triggered
by this journal button.
I want it to take me
back to a view controller
in my main storyboard
file that manages the UI
for creating a new
journal entry.
To do that, I'm going to scroll
over to my photo view controller
over here and I'm going to
drag out a storyboard reference
from the library and
drop it next to it.
Let's take a look at
the Attributes inspector
for a storyboard reference.
As you can see, there
are three fields here.
The first field is the name
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
The first field is the name
of the storyboard file
you're referencing.
If you leave this blank Xcode
will use the same storyboard
that contains the
reference itself,
which in this case would
be the photo storyboard.
That may be useful if you
have a really large storyboard
and you want to create a
segueway from a view controller
on one side to a view
controller on another side.
In my case, I want to reference
the main storyboard so I'm going
to choose main from the menu.
The next field is the identifier
of the view controller
you're referencing.
If you leave this blank Xcode
will use the initial view
controller of the
referenced storyboard.
In my case, I want to
reference a specific controller
in my main storyboard
and I have given
that controller the
identifier new journal entry.
The last field here is
the bundle identifier.
Your storyboard that
you're referencing might be
in an external framework.
In that case, you'll want
to put the framework's
bundle identifier here.
I'm going to leave it blank
because my main storyboard is
in the same bundle as
my photo storyboard.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
in the same bundle as
my photo storyboard.
Once again, now that my
storyboard reference is
configured, if I double-click
on it, Xcode will take me
into my reference
storyboard file
and show me the view
controller I'm referencing.
In this case it is a navigation
controller and if we take a look
at its Identity inspector
you can see
that I have given it the
same identifier I just typed
in the reference.
The root view controller of this
navigation controller is this
table view controller
which manages the UI
for creating a new
journal entry.
Let's head back to
the photo storyboard
and create a segueway
to that reference.
Earlier I mentioned that I want
this segueway to be triggered
by this journal button.
You don't see that
journal button here
in my photo view controller.
That's because that menu
is up here in the SceneDoc.
The SceneDoc allows you to store
top level objects alongside your
view controller and you might
put a view in your SceneDoc
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
view controller and you might
put a view in your SceneDoc
if you don't want that
view to initially be a part
of the view hierarchy
at runtime.
In Xcode 7 when you put
a view in your SceneDoc
and you select it, it
shows up in its own editor
above the view controller
right there in the canvas.
[Applause]
>> TONY RICCIARDI: So now that
we can see the journal button,
let's create that segueway.
I'm going to control drag over
to my storyboard reference
and I want to present this
view controller modally,
so I'll choose that.
All right.
Let's see this segueway
in action.
So the first thing I
want to point out is
that my photos tab is showing
up just like it did before,
even though now it is
coming from a separate file.
If I tap on a cell and
bring down the menu and tap
on the journal button we
execute that segueway which goes
into our main storyboard
file and instantiates
that view controller by its
identifier and it works just
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that view controller by its
identifier and it works just
as if it was in the
same storyboard.
That's our new Storyboard
Reference feature
and I hope you find it useful.
Now I'll hand you
back over to Kyle.
[Applause]
>> KYLE SLUDER: Thank you, Tony.
Okay. So I gather that
everybody is really excited
about that feature.
We're really happy
to have been able
to bring it to you this year.
[Applause]
>> KYLE SLUDER: Let's talk
about something different.
Let's talk about how
you can customize some
of the standard segueways
that we provide
for you in Interface Builder.
Looking at a different aspect
of our demo application here,
we have a journal that is
implemented using a table
view controller.
If the user taps that
plus button at the top
of the journal we want to
do a modal presentation just
like Tony showed you before
with the journal button
and that's going to bring
up navigation controller
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that has a table view
controller inside of it.
Tap the cancel button, that
navigation controller goes away.
That's the standard modal
presentation style coming
up from the bottom of
the screen and going back
down to the bottom of the screen
that you see on an iPhone.
What if you want to be fancy?
User taps the plus button,
we perform our segueway,
we want to be sparkly!
And if we're going to be fancy
in the incoming direction,
we really want to be equally
fancy when we're going away.
You might be familiar,
if you are an experienced
storyboard user,
with some of the options you
get when you select the segueway
and look at the segueway
inspector.
There are a couple of
standard transitions
that a modal presentation
can take on in iOS.
The default is coming from the
bottom, its that cover vertical,
but we can also do a horizontal
flip or cross dissolve,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
but we can also do a horizontal
flip or cross dissolve,
but sparkly, really
isn't in this list.
One thing we can do in iOS
8 using earlier versions
of Xcode is we can
go and we can turn
that into a custom segueway.
At that point we're responsible
for subclassing
UIStoryboardSegueway
and doing all of
the work ourselves.
That's not really all that
big a burden when it comes
to actually presenting the view
controller, but it would be nice
if we didn't have to do that.
Specifically in this case we
need to do a bunch of work
to set up the animation.
In Xcode 7 when you're
targeting iOS 9
or OS X 10.11 you can select any
of our standard segueway types
and still be able to
specify a custom subclass
of storyboard segueway.
You over-ride the perform
method just like you would
for a completely custom segueway
but now your implementation
of perform can call up
the supers implementation
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and get the default behavior.
Around that super call you can
perform whatever customizations
you want.
What's really important
about this
for our modal presentation
case is that we will hang on to
that segueway object that gets
created when the user triggers
that segueway for
the entire time
that your modal presentation
is onscreen.
Usually segueway objects
are really transient,
we perform the segueway, we
allocate a segueway, we send it,
perform, deallocate it,
but we're going to hold
on to your modal presentation
segueways and popover segueways
on iOS for the duration that
the view controller is onscreen
as long as you call
up the super.
Why am I making a
big deal out of this?
We need to go through how
you would actually implement
that custom sparkle animation
or any custom modal
presentation animation.
We've got our application
nice and tiny up here,
and the user has tapped the
button to trigger the segueway.
The destination view controller
exists, it has been instantiated
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
The destination view controller
exists, it has been instantiated
from the storyboard but has
not been put onscreen yet.
We're going to send
perform to the segueway,
and the first thing that our
override or perform needs
to do is assign a
transitioning delegate
to the destination
view controller.
Then it will call super to begin
the normal modal presentation.
Now the destination
view controller,
when it gets
presentViewController
which is done by supers
implementation or perform,
is going to consult with
the transition delegate
to bend another object
that actually drives
the custom animation.
For more details on how this
series of protocols works,
I suggest that you check out the
custom transitions using view
controller section
from WWDC2013.
Now in the other direction,
one the user is done
with our view controller,
they tap the cancel button.
The destination view controller,
since it is going away still
has a transitioning delegate
assigned to it and asks
that transitioning delegate
for an animation controller
to drive the dismissal.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
for an animation controller
to drive the dismissal.
If we didn't hold on to our
segueway which in turn holds
on to our transition delegate,
this all would have
been released
and in iOS 8 we probably
would have a crash here,
in iOS 9 it is a weak pointer
so we wouldn't have gotten
our nice custom animation.
Then animation controller gets
asked to drive the dismissal
and our fancy view goes away.
Another case where
this is important is
when you are handling
adaptivity.
For example, if you're
running on a iPhone
and the user rotates the
device, maybe an iPhone 6 Plus
and you want to present a
different interface in landscape
or portrait or you
have taken advantage
of the new multitasking
features in iOS 9 when running
on an iPad Air 2, and the
user has split your app 50/50
and you don't want to have, say,
a popover in the
compact presentation.
This specific example comes
from a talk on Tuesday,
getting started with
multitasking on iPad in iOS 9
which explains why you would
want to do something like this
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
which explains why you would
want to do something like this
and in the cases in
which this would occur.
Similarly to our
custom animation,
we need to use the delegate
to customize the presentation.
Our user is going to trigger
whatever segueway brings
up the modal presentation and
our overrider perform is going
to assign an adaptive delegate
to that destination
view controller's
presentation controller.
It is just the delegate
property,
but the protocol is actually
called adaptive delegate.
Then we call super in order
to get the standard
modal presentation
to popover a full
screen, whatever happens
to be appropriate for
the current size class.
Later on the user does something
to cause the size class
to change this, rotates
their iPhone 6 Plus,
does 50/50 in split
view on iPad air 2.
The presentation
controller is going to inform
that adaptive delegate that
we're changing size classes
and will turn around to
ask that adaptive delegate
to have a new view controller
to temporarily replace
the view controller
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to temporarily replace
the view controller
that is currently
being presented.
For more information
on how this works,
last year my boss gave
a great presentation
on view controller advancements
on iOS 8, last year,
not two years ago, but to
show you how this works today,
Tony will use Xcode 7 to
give us a custom animation.
[Applause]
>> TONY RICCIARDI:
Thank you, Kyle.
In this demo I will show you
a few ways you can add custom
Logic to your segueways
with code.
If you've used storyboards
before you have probably written
code to pass along data from
a source view controller
to its destination while
preparing to execute a segueway.
What you may not know is it
is also possible to customize
when a segueway triggers
or how it animates.
To show you that, I will create
a segueway here and specifically
when a user taps
this delete button,
I want to conditionally
present a confirmation sheet
if this photo here is
associated with a journal entry.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
if this photo here is
associated with a journal entry.
The first step in doing that is
to drag out of view controller
from the library which
will represent our
confirmation sheet.
I give this view
controller a custom class
which I have already
added to the project.
This class implements load view
to create its view
from the code.
The view controller doesn't
need this view that came along
with it from the library.
I'll click on the
view and remove it.
Now that this view controller is
no longer going to get its view
from its storyboard, at runtime
the framework will fall back
to my view controller's
implementation of load view.
Now that we have our
confirmation sheet view
controller let's
create a segueway to it.
I want this segueway to be
triggered from code rather
than from a particular
button press.
Rather than dragging out
the segueway from a sub view
in my view controller's
hierarchy I'll drag it
out from the view
controller itself.
To do that, I'll control
drag from this icon
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
To do that, I'll control
drag from this icon
in my sourceViewController
SceneDoc
over to the destination.
Once again, I want to present
this view controller modally.
I want the code that
executes this segueway
to be triggered by
the delete button.
What I want to do now
is create an IB action
from the delete button.
I open up the assistant
editor taking me
to the implementation file
for my photo view controller.
Now I'm going to control-drag
from the delete button
over to my source code and
I get a popover allowing me
to configure my new connection.
As I said, I want this to
be an action and I'm going
to call it delete photo.
Xcode generates an IB action
method and now I'm just going
to paste in some code here.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
There you go.
In this code it checks if there
is an associated journal entry,
if so it calls perform
segueway with identifier
and the identifier pass
in here let's me refer
to that segueway we just
created in the storyboard.
I'm going to give that
segueway the same identifier
in just a moment.
First I want to point out I
also referred to that identifier
from my prepare for
segueway method.
In this method I pass along
that associated journal entry
to the destination view
controller, which allows it is
to present the details
of that journal entry
in its confirmation sheet.
Now let's head over
to the storyboard
and select the segueway and head
up to the Attributes inspector.
I'm going to type in that same
identifier here, confirm delete.
You may notice if you used the
segueway Attributes inspector
before, there is a new
field under the identifier
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
before, there is a new
field under the identifier
which allows you to specify
a custom segueway class.
In Xcode 7 you can now
provide a subclass for any
of the system provided
segueway types.
This works both on iOS
9 and Mac OS X 10.11.
I have a custom segueway
I have added to my project
and I will choose that here.
It is called scaling
animation segueway.
Let's take a look at the
implementation for that class.
I'm going to close
the assistant,
then I'll use the
jump bar to head
over to my scaling
animation segueway.
The first thing I
want to point out is
that this segueway derives
from UIStoryboardSegueway
and then conforms
to the protocol UIViewController
transitioning delegate.
This protocol allows
you to vend objects
which control the animation
both for the presentation
and for the dismissal
of the modal child.
First I override the
perform method and in
that method I set the segueway
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that method I set the segueway
as the destination view
controller's transitional
delegate and I call super
which kicks off the
modal presentation.
Next I override two methods
from the transitioning
delegate protocol.
Animation controller for
presented controller,
and animation controller
for dismissed controller.
The objects that I return from
each of these methods conform
to the UIViewController
animated transitioning protocol.
In this protocol, it
contains the methods
that actually control
the animation.
Down here in my presentation
animator I have a pretty simple
animation which scales up the
destination view controller
from the center of the screen.
Let's see the segueway
in action.
All right.
Once again I'll tap on a
cell and bring down the menu.
When I tap on this delete button
our custom segueway executes
with our custom animation.
We see our confirmation sheet.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We see our confirmation sheet.
Now when I cancel this we run
our dismissal animation using
our dismissal animator.
So you saw a couple of different
ways you can customize your
segueways with code and
I encourage you to check
out the rest of our segueway
API on UIViewController
and UIStoryboardSegueway.
That wraps up our demo
on custom segueways.
Again, let's head back to Kyle
to take us to the next segment.
[Applause]
>> KYLE SLUDER: Thank you.
So I know it is an
advanced crowd here,
pretty experienced
with storyboards.
How many people here have
used unwind segueways before?
Substantially fewer than have
used storyboards themselves.
How many people here have
implemented a custom container
view controller on iOS?
About the same number.
One thing that I'm
really excited to talk
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
One thing that I'm
really excited to talk
about this year is how we have
made those two features work
better together.
For those of you that aren't
familiar with an unwind segueway
and what it does,
the best analogy
that I have found is the map.
So imagine I'm hanging out
here at Grace Cathedral,
which is that really nice
geometric church that's
up on Nob Hill, you can see
it from places from downtown.
And it being at the
top of a hill,
figure we'll take a
nice long downhill walk
to the ferry terminal.
Hang out at the ferry terminal
for a bit, get my organic kale
and my blue bottle coffee and
since I'm on the Embarcadero,
I may as well take a nice long
flat walk to Fisherman's Wharf.
Now I'm really tired.
I want to go home.
What I don't want
to do is turn around
and come back the way I
came because A, I don't live
at the Cathedral, and B, that's
not even the shortest way
to get to the Cathedral.
What I want to do is first
figure out where I'm going,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
What I want to do is first
figure out where I'm going,
second, find that
location, and third,
plot and execute a route
to that destination.
That's what unwind segueways do.
They find a path to a
specific destination
that doesn't necessarily
mean that we go backwards
through the way we came.
To give you a more concrete
example using an actual
application let's go back
to this demo application
we have been using
with our tab bar controller...
sorry, our custom tab
controller and the table view
and its navigation
controller that contains it.
As the user uses
our application,
our view controller
hierarchy changes.
They may tap on an
image and push something
into the nav controller
that is a child of that tab.
That's where we're at right now.
At this point the user
says I want to go back
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
At this point the user
says I want to go back
to that journal table I
was looking at before.
So when they ask to do that,
we're going to perform
a segueway
from our photo view controller.
It is an unwind segueway with
the identifier goBackToJournal.
The first thing that
unwind segueway needs
to do is identify
the destination.
The way we find our
destination, the way we dermine
that we've found what
we're looking for,
it is with some code.
That code is in our subclass
of UITableViewController
and it is a method that I have
chosen to call iAmTheJournal.
That method doesn't do anything.
It is an ID action that takes
a UI storyboard segueway
and exists solely so
that we can determine
that we have found the view
controller we are looking for.
Step two is finding
the destination.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Step two is finding
the destination.
So we start by looking at the
parent of our current source.
In iOS 8 we ask this view
controller -- excuse me.
In iOS 8 we ask this
view controller,
viewController
ForUnwindseguewayAction.
This view controller would look
through its children trying
to find a view controller
that responded
to that iAmTheJournal selector
that we have specified here.
We have set that
up in the inspector
for our unwind segueway.
That method is great for smaller
view controller hierarchies
but doesn't really
handle the kind
of viewer controller hierarchy
we have in this application.
In iOS 9 we have deprecated
that method and replaced it
with a new method, allowed child
view controllers for unwinding
from source, and what
this method returns,
instead an individual view
controller, returns an array
of the children of the
receiver that we should look
through to try to find
the destination So we want
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
through to try to find
the destination So we want
to actually return a
subset, we don't want to try
to find an unwind
destination that's a descendant
of where we're coming from.
We also have another new method,
child view controller
containing segueway source
that are an override of allow
child view controllers can use
to figure out where
we're coming from.
The implementation on UI
navigation controller calls
that method to figure out where
we're coming from and says, oh,
that photo view controller
is the source,
therefore contains the source.
The returned array of child
view controllers omits
that view controller and
we get an array of 1.
At this point the
storyboard runtime recurses
into that array starting with
the first and only element.
We ask this, the collection
view controller that's currently
obscured what children do you
have that we should search
through to find the destination
of our unwind segueway?
It doesn't have any children.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We have the base case for
our recursion and we ask it,
can you perform the unwind
segueway action we're
looking for.
It can't. We haven't
found our destination.
Let's try the search
again one level
up the view controller
hierarchy chain.
Same method as before, this
new method allowed child view
controllers from
unwinding from source.
Its implementation, our
custom view controller,
only wants to go backwards,
vertically up through
that stack.
It asks itself which of
my children contains the
unwind source?
That photo nav controller
contains the source
so the array it returns
omits that child.
We have again an array of
one child that we're return
from this method and
the runtime recurses.
Which of your children
should we look
through to find the
unwind source?
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I'm sorry, the unwind
destination.
This navigation controller
doesn't have any --
doesn't have the source
of the descendants,
we can skip over that for
now and we recurse again.
We ask the Table
view controller,
which of your children
should we look
through to find the destination?
It doesn't have any children.
We ask it, can you perform
the unwind segueway action?
That's what that method is
that I implemented earlier
that didn't have actually any
body to its implementation.
That's our sentinel, we found
it, we found our destination.
Now at this point, in iOS
8 we would ask the parent
of our destination to return
us a segueway that knows how
to restore our view
controller hierarchy
such that our destination
is visible.
That's a really hard
question to answer
for more complicated view
controller hierarchies.
We have deprecated that
method and we replaced it
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We have deprecated that
method and we replaced it
with a feature we call
incremental unwinding.
This feature let's every view
controller from the source
to the destination
participate in the unwind
so that it only needs to
use the local knowledge.
The runtime will construct a
UI storyboard segueway object
for you using whatever subclass
you specified in the inspector
and Interface Builder.
It will ask it to perform.
Here is step three,
follow the route.
Well, we have found the route
from the source to
the destination.
The first thing we're going
to do is ask the first hop
on that route to unwind
for segueway towards
view controller.
We're going to ask the
parent of the source
to perform whatever action
is necessary to get us
to the next step in the chain.
The child view controller
doesn't know anything
about its parent.
This method actually
doesn't do anything.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
This method actually
doesn't do anything.
It has been told unwind
towards your parent,
that's not the child's
responsibility.
Next we get to our custom
container view controller.
We ask it, okay, unwind
towards our journal
navigation controller.
This is something that the
custom tab controller is
actually responsible for and it
knows how to rearrange itself
so that the journal navigation
controller is visible.
Next up on the chain we ask our
navigation controller to unwind
to the table view controller.
It is already at the top
of the navigation stack
so there is nothing to do here.
We returned where
the user wants to go.
This is how all this
stuff works internally.
Tony will show you how
to implement it in
your application.
[Applause]
>> TONY RICCIARDI:
Thank you, Kyle.
In this demo I'll show you
how to use unwind segueways
with a custom container
view controller.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
You might remember in our first
demo we created a segueway
from this journal button.
This modal sheet for
creating a new journal entry.
Unfortunately we haven't
implemented any functionality
for this done button.
What I want to do now is
create an unwind segueway
from this done button and I want
that unwind segueway
button to do a few things.
First of all, I want it to
dismiss this modal sheet.
I want it to pop my
photo view controller off
of the navigation stack.
I want it to switch tabs
over to my journal tab.
I want it to descend
down through this navigation
controller and finally end
up at this table view controller
where we'll insert a
new table view cell
for the new journal entry.
That's a lot to ask
for one segueway.
Where do we get started?
The first step in creating
an unwind segueway is
to define a special
type of IB action method
in the view controller
you're unwinding to.
In this case, it is our
journal table view controller.
Over here in the implementation
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Over here in the implementation
for that controller you can
see I have an IB action method.
And this IB action
method is special
because it is taking
a UIStoryboardSegueway
as its only paramater.
Whenever Xcode sees an IB
action method it takes a
UIStoryboardSegueway as its
only paramater and allows you
to create unwind segueways
targeting that selector.
Within this method I grab
the source view controller
of the segueway which in this
case is that view controller
for creating a new
journal entry.
I use that view controller's
journal entry and add it
to our model which refreshes
the table and inserts a new cell
and scrolls to that
cell's position.
Now that we have seen the action
that we're unwinding towards,
let's head over to
our storyboard
and create a segueway
targeting that selector.
Here we aree at the
view controller
for creating a new journal entry
and we'll create an unwind
segueway from this done button.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
To do that, we'll control-drag
from the done button
to the exit place
holder in the SceneDoc.
The exit place holder serves
as a place holder for all
of the valid unwind actions
that Xcode has found
in your work space.
It determines that a method is
a valid unwind action once again
based on whether it
is an IB action method
that takes a
UIStoryboardSegueway.
It found that method we saw
so I'm going to select that.
Normally when you create an
unwind segueway that's all you
have to do.
You define the unwind selector
and create the segueway to it.
In my case I want to
execute some custom logic
which allows my custom
container view controller
to switch between these tabs.
That logic is in my custom
container view controller file
so let's head over there.
As you can see, in this
view controller I have
over ridden unwind for segueway
towards view controller.
In this method I do two things.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
First of all, I take the
currently selected navigation
controller, and I pop that down
to the root view controller.
Then I set the selected
navigation controller
to be this parameter
subsequent view controller.
Subsequent view controller
is the next step
in the unwind chain.
It is not necessarily
the end destination
of the unwind segueway,
it is a direct child
of this custom container
that we're unwinding towards.
The did set observer for this
property, is going to take care
of updating my auto layout
constraints and performing
that sliding animation
we saw earlier.
Now that we have seen my custom
container view controllers'
implementation of
incremental unwinding,
let's see this unwind
segueway in action.
I'll tap on a cell.
Bring down the menu.
I tap on that journal button.
Now I'm going to
tap the done button.
You can see we have
switched tabs.
We have ended up at our
journal view controller
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We have ended up at our
journal view controller
and inserted this new table
view cell for our journal entry.
As you can see, unwind segueways
have gotten a lot more powerful
in iOS 9 and they work great
with custom container
viewer controllers.
[Applause]
>> TONY RICCIARDI: So that
wraps up our unwinding demo.
Now let's head back over to Kyle
one last time to wrap this up.
>> KYLE SLUDER: Thank you, Tony.
So just a quick summary
of the new API we have
introduced for unwinding.
We have deprecated
viewer controller
for unwind segueway action
and we have replaced it
with allowed child
view controllers
from unwinding from source.
If you override the old method
and don't override
the new method,
we will call the old
method even on iOS 9
so that your code behaves the
same if your app targets iOS 8
and it can also run on iOS 9.
The implementation of
that override my want
to call the new allowed child
view containing controllers
for segueway source method so
that it can filter the array
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
for segueway source method so
that it can filter the array
of child view controllers
that it returns.
If you need some sort
of custom validation
for whether you can perform a
certain unwind you can override
the can perform unwind segueway
action method which has existed
for a while but by
default all it does is see
if the receiver responds
to that selector.
Usually that's sufficient.
Likewise, we have
deprecated the segueway for --
segueway for unwinding
to view controller method
and replaced it with unwind
for segueway which is called
on each view controller
in the chain
to implement incremental
unwinding.
Overall, today we learned how
to organize our storyboards
using references.
We learned how to customize our
segueways by subclassing them.
Even though we want to
get the standard behavior.
We learned that in iOS and iOS
9 specifically, present modally
and popover presentation
segueways will hang on to --
sorry -- the view
controllers that are presented
by present modally and popover
presentation segueways will hang
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
by present modally and popover
presentation segueways will hang
on to the segueway
objects that presented them
so that they can
act as delegates
for animation or for adaptivity.
We have learned how
unwind segueways work
to get us backwards
through our application flow
and that we can support them
easier in our custom containers
and remove our deprecated
APIs in order
to get the behavior in iOS 9.
If you need more
information on storyboards,
the storyboard help has
been rewritten in Xcode 7,
so you should check
that out first.
We also have a sample
project, segueway catalog,
which is available on
the developer website.
There actually isn't a space
in that name so if you search
for segueway in the
space catalog,
you find the wrong thing.
If you need technical support,
check out the dev forums.
There are a lot of developers
out there just like you,
facing the same problems you
have have been posting on there,
are able to help you
figure out your problems,
you can contact developer
technical support
or if you have general
inquiries,
contact Curt Rothert,
our evangelist.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
contact Curt Rothert,
our evangelist.
Otherwise, maybe I'll
see you at the bash.
[Applause]