Transcript
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
[ Silence ]
[ Applause ]
>> Jacob Xiao: Hello everyone.
You've all seen iOS 7's
amazing new design and big part
of that change is there's
a lot less ornamentation,
which is a big part of
what used to make a lot
of applications unique.
So you may be wondering how you
can make your application stand
out in this new world.
Well, there's still
a lot of ways
that you can customize your
application including several
new ones.
So today, I'd like to talk
about how you can
customize your application
to make it still have its
own unique appearance,
but fit in with the rest
of the iOS 7 design.
I'll be talking about
three things today: First,
some of what's changed for
customization in iOS 7.
Then, some advanced topics
for how you can customize
your application
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and finally how you can create
your own custom controls
that work just as well
as our UIKit controls.
I'll be using a sample
application today
that looks like this.
It's a simple application that's
a combination of messaging
and what I think is the greatest
game of all time, Tic-Tac-Toe.
I think it's going
to be a big hit.
This is what it looks
like today.
It's a simple standard
uncustomized iOS 7 application,
but we're going
to be customizing it
to look like this.
And I'll be telling you all
of the different customizations
we use and how you can use them
in your application as well.
And one important note
about this application is
that it's actually available
as sample code for you
to download and look at.
Just go to the developer website
and in the prerelease section
search for Tic-Tac-Toe.
And I encourage you to
take a look to see how all
of these technique works.
But before I start, I wanted
to mention one thing and that's
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that all of the existing
customization techniques
that we had still
work great in iOS 7.
And we use a lot of these
in the sample application,
things like UAappearance
customization
and resizable images.
I'm not going to be
talking about those today,
but you can look at the last two
years appearance customization
talks in the last two WWDCs to
check out some of the concepts.
Alright, let's get started
with some of what's changed
for appearance customization
in iOS 7.
One of the first things you'll
notice is the Status Bar.
The Status Bar has an entirely
different look in iOS 7
and it has two different
styles that you can use.
The default style shows dark
content on a white background
and we have the new style called
US Status Bar Light Content,
which shows light colored
content on a dark background.
However, neither of these
two styles actually draw the
background themselves.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I've shown them here with
black and white backgrounds,
but they're actually
fully transparent.
And this means a lot for
how you draw the Status Bar.
You can now customize the
background that's behind it
by showing anything
you want there.
Of course, you'll want to
be careful to make sure
that you provide a background
that keeps the Status
Bar readable
by giving it enough contrast
and not being too busy,
but you have a lot
of freedom here.
And so, part of how we've let
you draw this background is
by changing the way that we lay
out view controllers in iOS 7.
We'll now layout the content
of your view controller
beneath the Status Bar,
which is what allows you
to draw this background.
So if you'll look
at what we've done
in our sample application we
have a simple white background
and we're careful to not show
our game content underneath the
Status Bar to keep it visible.
However, in other views
in our sample app,
we actually haven't
done anything
for the background
of the Status Bar.
So, here in the messages
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and profiles view we're using
a navigation controller.
And any time that use a
navigation controller it will
actually draw the background
beneath the Status Bar
for you automatically.
It does this by taking the
background of the navigation bar
that it shows and extending it
to go beneath the Status Bar.
This happens for
you automatically
if you're using a
navigation controller
so you don't have
to worry about that.
Alright, there's
another implication
of this Status Bar
change on your application
and that's the default.png
images you use.
These are what we're using
in our sample application
for our startup images and
the important thing here is
that they have to be
full-screen size images.
So that means 320 x 480
points and 320 x 568 points.
And this allows you to draw
in your default.png
images backgrounds
that goes behind the Status Bar,
but don't include the Status Bar
itself in your default.png image
and that way as your application
launches we'll draw a live
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Status Bar on top of it
and it'll look great
as you start out.
We've actually gone a little
further and made it easier
for you to create your own
default.png images in iOS 7
by introducing a new system that
allows you to set multiple sets
of default startup images for
different versions of iOS.
Previously you could only have a
single set that was used for all
of the versions of iOS
that your app ran on.
In iOS 7 we're introducing
a new key
that you can use
in your info.plist.
Just add the UI launch
images values
and you can add a dictionary
with different information
for kind of default.png
images you want to use.
And if you want to see all the
details of how to set this up,
check out the sample
application which uses this.
But the important thing
is that this allows you
to set different minimum iOS
versions for your different sets
of default.png images.
So you can now create a
full-screen sized default image
for iOS 7 but still keep
your older default images
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
for older versions of iOS.
Alright, now you may
have seen that many
of our system applications have
their own different key colors
in iOS 7.
And this color is used for
drawing interactive elements
in the application and
also selectable elements.
So, if you look at the buttons
here and also the current day
and calendar you'll see that
they have different colors
in these different applications.
And this is a lot
of what you can use
to make your application
different in iOS 7.
So even if you don't use any
other customization techniques
I'd really encourage you to
choose your own key color
for your application in
iOS 7 and we've tried
to make this really
easy for you to do.
In fact, you can customize
the color, the key color
of your entire application with
just this one line of code.
So, the way this works
is by extending a concept
that we've had for
a while in UIKit
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and that's called Tint Color.
Tint Color used to be a property
that several controls and views
in UIKit had and affected how
they drew their own content.
But now we've taken Tint Color
and added it to every UIview
and it also has some
new behaviors.
One of the most important
behaviors
of Tint Color now is the
new inheritant system.
And the way this works is
that when you set a Tint Color
on one view like the window it
will actually flow down to all
of the subviews of that window
and recolor them as well.
So when we set the red color
for our window we're
actually recoloring the Pause
and New Game buttons and also
the content in the Tab bar.
So, with this change to how
Tint Color works the Tint Color
Property that used to exist
for navigation bars now
has a different meaning.
In iOS 6 if you set
the Tint Color
for a navigation bar it
would recolor the background
that was shown for the bar.
So, if you set it to red
you'd get this appearance.
Now, if you ran that same code
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
in iOS 7 you'd get
something very different.
As I said, changing the tint
color now affects the foreground
interactive elements
that are shown.
So if you now set the Tint Color
to red notice that the buttons
that are in the navigation
bar are changed
to red instead of
its background.
If you still do want to
change the background
of the bar itself we've
added a new property
that you can use to do that.
All you have to do is set
the Bar Tint Color your bar
to whatever color
you want to use
and that will change
the background
of the bar instead
of its foreground.
Of course, you can
combine these as well
to set a different background
and foreground color.
So, that's the new Bar Tint
Color and you can use it
on navigation bars, tool bars,
search bars and tab bars.
Another way that you can
customize the backgrounds
for your bars is by setting
custom images on them just
as you've traditionally
done in iOS.
And we're going to be using
that for our sample application
to set this custom image that
looks kind of like a grid
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to match with our
tic-tac-toe theme.
Now, traditionally in iOS
you would set a 44 point tall
background as your
custom background image
and this way it would be
shown beneath the bar,
which is 44 points tall
and we would show a black
background beneath the Status
Bar and you can still
do that in iOS 7.
But as I mentioned earlier,
navigation bars now often
show a full larger content
that shows the background
beneath the Status Bar
to get a kind of
unified look there.
And you can participate
in this system
with your custom
background images as well.
To do that, all you have
to do is set a 64 point tall
background image instead
of 44 points.
When you do this,
we'll automatically
extend the backgrounds
to go beneath the
Status Bar as well
and if you're wondering the
64 point height is the 44
of the navigation bar plus the
20 points of the Status Bar.
So this is what we'll be doing
in our sample application using
the full height background image
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and this-- these changes apply
to landscape size
background images as well.
So, in those cases you
would use 32 points tall
for just the navigation bar
background images or 52 points
if you want the combined look.
Now, when you use
navigation bars most
of the time they appear at
the top of your application,
but they can also
appear lower down
and not part of the Status Bar.
This usually happens
when they're used
in things like popovers.
And we've actually
introduced a new system
so that you can set different
custom background images
for these two different cases.
To do this you can use a new
setter called setBackgroundImage
for bar position,
barMetrics and this allows you
to specify the top attached
bar position for the case
of a combined Status
Bar and navigation bar
or just the top bar
position if you want
to customize the background of
a bar when it appears by itself.
So this way, you can set
different custom background
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
images that have
exactly the right height
for the navigation
bars where it appears.
And if you want, you can
also use the bar position,
any bar position to set a
custom background images,
image that applies
to both cases.
And this is great if you have
a vertically resizable image
because it will just be shown
at exactly the right size.
Now, in older versions
of iOS we had a behavior
when you set a custom
background image on a bar
where if the height of your
background image was taller
than the bar's height we
would extend that background
to go beneath the bar and
into the content below.
And this allowed
you to do things
like have a shadow effect
inside of your background image.
But because of this new behavior
where the background image
of the bar can extend behind the
Status Bar we no longer support
that older shadow behavior.
However, instead you can use
a property called shadowImage
that we introduced in iOS 6.
This lets you set your own
dedicated shadowImage that's
shown in just an area beneath
your bar and above the content
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and that allows you to create
exactly the custom shadow image
that you want instead
of including it as part
of an overly tall
background image for the bar.
So another big change with
bars in iOS 7 is Translucency.
By default, all of our
bars are now translucent
and this includes
both the default
and the black style navigation
bars and it also applies to bars
that you've set a custom
Bar Tint Color for.
When you set a custom background
image the behavior is a little
bit more complex, will actually
analyze the background image
that you set for the bar
and determine whether the
image has any transparency
in it or not.
We'll use that determination
to set the Translucent Property
of the bar so that it
matches what you've set
as a background image.
So these are all of the
default values that bars have
for a Translucent Property,
but if you want to override
that you can always set the
Translucent Property directly
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to whatever you want.
And this will, of course,
change the appearance of the bar
but it'll actually
also have an effect
on how view controllers are laid
out in relation to that bar.
So by default in iOS 7, if
you have a view controller
that appears with bars like
this top navigation bar
or bottom tab bar, if the
bar is translucent we'll lay
out your view controller
such that it's
under both of those two bars.
However, if those bars are
opaque then we'll just lay
out your view controller
in the area between them.
So, this is something
to keep in mind
as you're designing
your view controllers
and how they're laid out.
And there are also places
that you can set the different
behavior of these properties
in the UIView controller.
I don't have time to
talk about all of--
how all of this works
today, but you can look
at the UIView controller header
to see details of
how that works.
Now, another change that
you'll see with the buttons
that appear both the
navigation bars and in the rest
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of your application is that
they no longer show any bezels
around them by default.
The new default appearance
of our buttons is
that they'll show either
their text or their image
and the tint color
that they have.
So as you can see, we have
this Edit and Compose buttons
and they don't have any bezels.
If you'd like to use some kind
of outline, background or bezel
in your buttons you can
actually still use all
of the customization
techniques that we've had before
to set a custom background
image for your buttons
and this will still draw bezels
just as it has traditionally.
And this applies to the
Back Button as well.
Here, you'll notice that the
Back Button shows just the back
text and back chevron.
And this is the default
appearance that you can custom
in actually two different ways.
As I said, you can use our
traditional older methods
to set a background image
for your Back Button
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and if you do that,
we'll actually turn off the back
indicator chevron that's shown
here, because generally you'll
include a back indicator as part
of your background artwork.
However, if you want to continue
with the background list
appearance of our buttons
as we're doing in our sample
application then instead you can
customize the back
indicator chevron.
To do that we've
introduced a new property
to UINavigationBar
called backIndicatorImage.
And this lets you set your
own custom back chevron.
This is the one we're using
in our ample application.
It's kind of a combination of
the back chevron with the X
from the tic-tac-toe game
and that's what it
looks like in context.
However, one thing you
want to keep in mind
as we're customizing this back
indicator is that it's also used
for push and pop transitions
of the navigation bar
to make the text of the
Back Button flow into
and out of the back chevron.
So to do this effect,
we actually show--
use a mask image that's
a triangular shape
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to mask the text as its
moving during the transition.
And if you're changing the
back indicator then you'll want
to change this mask
image as well.
And you can use this
other method
backIndicatorTransitionMask
Image
to set a custom image for that.
And in fact, these two
properties are closely
linked together.
So if you want to customize
the back indicator you have
to set custom values for
both of these two properties.
Otherwise, we won't use the
custom image that you set.
This is our custom back
transition mask that we're using
in our application and notice
that when we use it the text
of the Back Button
as its flowing
in is clipped to exactly match.
As you're designing these two
images you want to keep this
in mind, the fact that they
should exactly fit together
so that the masking effect
works as the text is moving.
Alright, our application
also uses a Tab bar
as part of its appearance.
And the first thing you'll
notice about Tab Bars
in iOS 7 is that they're
now wiped by default.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
But they also have a
new bar style property
that matches the rest
of our bars in UIKit
and this lets you set either a
default bar style for dark text
on a white colored
background or a black bar style
to get the inverse, light
text on a dark background.
And this is exactly the
same behavior as all
of the bar styles
on our other bars.
[ Silence ]
>> Alright, now another
thing you'll see as you look
at Tab Bars in iOS
7 is that many
of them have different print
images for their selected
and unselected states.
So, if you look at this example
from the Clock application,
you'll see that all
of the images,
that all of the tabs have
different selected images
that are a little heavier
and they have more fills
than the outlines in
the unselected images.
We've made this easier
for you to do
in your application
in iOS 7 as well.
So, traditionally UItabBarItem
has had an image property
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that lets you set your own
image on the tab bar item
and that image was used both
when the tab bar items was
selected and unselected.
You can still use that now
but we've also introduced a new
property called selected Image.
And this lets you
set a second image
to override the image property
when the tab bar is selected.
So, if we use that in our sample
application we can set three
different images to have
a heavier look as well
when our different
tabs are selected.
So, that's Tab Bars.
Table Views also have
many changes in iOS 7.
One of the first things
you'll see is that instead
of the rounded rectangle
appearance group style table
views had in iOS 6, they now
have an end-to-end design
that looks more similar to
the plain style table views.
However, they still
do have differences.
The backgrounds are now a darker
gray and there's a larger space
between the different sections.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, redesigning your app
for iOS 7 you may want
to consider using Group Style
Table Views in different places.
Another change with table views
is their highlighted appearance
of the rows in Table Views.
Before iOS 7 we would show a
dark blue background behind a
selected Table View cell
and we would generally
invert the content
of the Table View cell
to appear in white.
However, in iOS 7 we show a more
subtle gray background behind
the selected Table View cell
and generally now we
don't invert the colors
of the content.
So as you're designing your
new Table View cells you should
consider leaving the
colors as they are
when your Table View
cell becomes selected.
Now additionally, if you'd
like to change the color
of the background that's
shown behind a cell
when it's selected you can still
use the same property we've had
for a while,
selectedBackgroundView.
This lets you provide
your own background view
for the cell that's used in
place of our standard one.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Something else we've introduced
in iOS 7 is the new button type.
We call this UIButton
Type System.
You can get it with the same
button with type method.
Now this button is a standard
system button just like the ones
that we use in navigation bars.
And this new button type
replaces the existing rounded
Rec button type, which is
now deprecated on iOS 7.
When you use this system style
button you'll get all the
default behaviors that
we use for our buttons,
which includes this
appearance where they're shown
without a bezel and with their
text or image in the Tint Color
of the application and you
also get several animations
and other effects for free.
So, you'll get a highlighted
effect that looks like this
where a window button is
tapped will change its opacity
to indicate that
it's being pressed.
And you'll also get a new
selected appearance just
by setting the selected
property of the button to Yes.
When you do that we'll show
the selection indicator to show
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that your button
has been selected.
So we're using these buttons
in our sample application
for the Pause and New
Game buttons and also
for this Reply Button that
we show in the messages view.
All of the other
controls that we have
in UIKit have all changed
quite a bit as well in iOS 7.
They all have different
appearances and many
of them have different
metrics as well.
And the best way to deal
with these metrics changes is
to use Autolayout
in your application
so that you remain flexible to
these changes and don't have
to hard-coat in different sizes.
However, despite these
appearance changes all
of the traditional methods
that we have for setting,
customizing images, colors and
text attributes still work great
on all of these controls.
So you can still
make them themed
to exactly match your
application just as you'd like.
Now, there's one
last change in iOS 7
that will affect how you set up
your customizations for your app
and that's Asset Catalogs.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Asset Catalogs are a new
system that we've introduced
that allows you to combine
all of the images that you use
into your application
into one resource file.
And this lets you
consolidate all of your images
and also gives you
several new capabilities.
You can now set different images
for different device types
and scales and you can
even do your slicing
of your images right
inside of Xcode.
So, I would highly recommend
that you use Asset Catalogs
for all of your custom images
in your iOS 7 application.
Alright, so those are some of
the basics of what's changed
with customization in iOS 7.
Now, let's talk about
some advanced topics.
Earlier I mentioned Tint Color
and how you can use one line
of code to change the tint color
of your entire application.
But what's actually
happening here?
When I showed you the
Tint Color on every view,
it's actually a little
bit more subtle than that.
Conceptually, you can think
of their being two different
Tint Colors on each view.
Now there's only one property.
This is just a conceptual
way to think
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
about how this property
works and try
to help you understand the
behavior of Tint Color in iOS 7.
So, I'll call these the Specific
and Inherited tint
color of the view.
The Specific Tint Color is the
one that you've set on a view
with a tint color setter.
The Inherited Tint Color on the
other hand is what you get back
when you call the
tintColorGetter
on the same view.
And these two are not
necessarily the same.
So, the reason that I call
it an Inherited Tint Color is
that if you haven't set
a specific Tint Color
on that view then it will
actually inherit the Tint Color
of its super view.
And if it doesn't have a super
view it will inherit a system
default color, in this
case, this blue color.
So, now if we look again
at the example from earlier
where we set a red tint color
on our window you'll see
that the setter sets
the specific Tint Color
for the window.
After that happens the Inherited
Tint Color will now use the
specific Tint Color
because it's non-nil instead
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of inheriting the
system default.
After that all of the
subviews that have nil
as their specific tint color
will inherit the tint--
the inherited Tint Color of
their superview, the window,
and they'll become red as well.
Then that process will
repeat until all of the views
in that window that did have
their own specific color have
adopted the red tint color.
Now, if we then change the Tint
Color of the window back to nil,
we've essentially erased
the Specific Tint Color
for the window, which
means it will go back
to inheriting the system default
and that change will be
inherited by all of its subviews
and so on until all of the
views in the window will go back
to the system default
blue color.
So, this same behavior applies
if you set the Tint Color
on a subview of the window.
So, now let's set the Tint
Color of this Tab Bar to green.
Once again when we
call the setter,
the setter for Tint Color we're
setting the Specific Tint Color,
which it then becomes
the Inherited Tint Color
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and which then is also
inherited by its children.
So now that we set a Tint Color
for this subview hierarchy
if we again go back and set
the windows Tint Color to red,
something a little bit
different will happen.
Once again, the Specific Tint
Color becomes the Inherited Tint
Color and now that
color is inherited by--
by only the children
that have a nil,
a nil Specific Tint
Color of their own.
So you'll see that the Pause
and New Game buttons become red,
but the Tab Bar remains green.
[ Silence ]
>> Alright.
So this is how you can
get different colors
for different parts of
your view hierarchy.
Now, there's one
additional special behavior
that Tint Color has and
that's related to what happens
when you show alerts and action
sheets in your application.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
If you look closely when this
alert is shown the background is
dimmed, but also all of the
places that show the Tint Color
of the application
have become desaturated
and that happens automatically
whenever an alert appears.
The reason we do this is
so that those tint colors
in the background
don't interfere
with your focus on
the alert itself.
And this is accomplished
by a new property
called TintAdjustMode.
TintAdjustmentMode is
closely related to Tint Color
and it can have these
three different values.
When it's set to normal then
we'll show the Tint Color
of those-- of every view as
its original saturated color
and when it's dimmed then we'll
automatically desaturate the
tint color of those
views for you.
And we'll come back
to the AutomaticTintMode
a little bit later.
So, let's take a look
at how TintAdjustmentMode
works for view hierarchy.
Every view has a
TintAjusmentMode property
as well and if you call the
getter it defaults returning
normal for all of these views.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Now, when an alert appears
it sets the TintAdjusmentMode
of the window to be dimmed.
Once that is dimmed then the
Tint Color that's returned
for the Inherited Tint Color
of that window becomes
a desaturated gray.
Then that will be inherited
similarly to Tint Color by all
of the subviews of the window so
those views will become dimmed
as their TintAdjusmentMode
as well,
which will cause their tint
color to be desaturated and so
on until the entire
window becomes dimmed
and has desaturated Tint Colors.
So, this is not only
something that happens
with system views like alerts.
You can actually incorporate
this into your own app as well.
And we've done this
in our sample application
in the Messages view.
Here when you tap on the
Compose icon we show a new
message sheet.
And when this sheet appears
we like it to look similarly
to how an alert appears.
So, we'll set the
TintAdjustmentMode of the window
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to be dimmed, but you'll notice
that there's a problem here.
Not only have we
dimmed the window
but if we show the new
method sheet inside
of the window then it will
become dimmed as well.
So, now our Cancel and
Post button instead
of being red are
desaturated to gray as well.
So, how can we fix that problem?
Well, when I showed you the
TintAdjustmentMode property
earlier, I left something out
which you may have guessed
by now and that's that there's
a second TintAdjustmentMode
conceptually as well.
And this has the same Specific
and Inherited TintAdjusmentMode
just the way the Tint
Color does.
The specific TintAdjustmentMode
review is what you've actually
set with the TintAdjusmentMode
setter
and then the Inherited
TintAdjustmentMode is what you
get back with the getter.
So again, this works the
same way as Tint Color.
And this is where the
AutomaticTintAdjusmentMode comes
into play.
When a view has the Automatic
Specific TintAdjustmentMode then
it will inherit its
superview's TintAdjusmentMode
and if its superview doesn't
have one it will use the system
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
default TintAdjusmentMode,
which is normal.
Again, this is the same
way the tint color works
where if the view has a nil
specific tint color it will
inherit its superviews and if it
has no superview it will inherit
the system default.
So, now if we look at the
example again from earlier
where we set the
TintAdjustmentMode of the window
to be dimmed we'll see
that we're setting the
Specific TintAdjustmentMode,
which becomes the
Inherited TintAdjustmentMode
when its non-automatic
and that's what desaturates
the color of the view.
And then it sends
all of our subviews
to Automatic TintAdjustmentMode,
they inherit their superviews
and become dimmed as well.
Then they become desaturated ad
that repeats throughout
the entire window.
So, this is where we
can take advantage
of the same thing we did
earlier with Tint Color
to created a green
subview hierarchy.
Now we'll set the
TintAdjusmentMode instead
of the Tint Color of this
subview, which is our Tab Bar
in this case to be normal.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Again, by setting the
TintAdjusmentMode setter we're
setting the Specific
TintAdjustmentMode.
Then, since it's not automatic,
our view will stop inheriting
from its superview and
become normal as well.
Since it's normal its color
will become resaturated and all
of its subviews that have
Automatic TintAdjusmentModes
will inherit that as well.
So, we'll have this
kind of island of color
within our greater
view-- our greater window,
which is otherwise desaturated.
Now that's what we can use to
bring back the color to our--
to our new message sheets.
But there's one last thing
that we'll need to do,
which is what we're going to do
when the new message
sheet disappears.
So, if we look at the red and
green example from earlier,
when we set the
TintAdjustmentMode of the window
to be dimmed once again that
will replace the inherited value
and desaturate all of
the views in that window.
But if you look carefully,
only the Inherited Tint
Colors are changing.
All of the Specific Tint
Colors remain the same.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, the red and green are
still there, they're just kind
of hidden by the
stimming effect.
And the great thing
about that is
that when we set the
TintAdjusmentMode
of the window back
to be automatic our Inherited
TintAdjusmentMode goes back
to normal and all of our
colors become resaturated
to the same colors that
they were originally.
So, our view hierarchy returns
to all of its reds and greens.
Alright, let's take that and
use it in our new message sheet.
So, here we have our window
before we showed the new
method sheet.
Then as we show the sheet
we'll set the windows
TintAdjustmentMode to dim
and the sheet's
TintAdjustmentMode to normal.
That way we get exactly what we
want where we have our Cancel
and Post button in red,
even though the rest
of the window is gray.
And finally, when we dismiss
the sheet we'll set the
TintAdjusmentMode of the
window back to be automatic,
so return everything
to its color.
So, that's the Tint Color and
TintAdjusmentMode properties
and how to use them in iOS 7.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Now, another part of
our Messages view is
in the Navigation
Bar at the top.
We have a Favorites
button that you can use
to favorite messages
that you're received.
However, this is the
artwork that we're using
for that Bar Button
item and notice
that it has a gold radiant
color in the artwork.
But when we actually use it
in the Navigation Bar it's
just getting color to be red.
This is generally what
you want actually.
If you look the Compose
button it's shown in red
and that matches the
rest of the Tint Color.
But with our Favorite button
we want to see this gold star
so people will really feel happy
when you favorite
their messages.
So, how can we fix this problem?
Well we're using a concept
called Template Images in iOS 7
to do this recoloring.
When an image is
a template image,
instead of being drawn as--
with its original colors the
image is treated as a stencil.
So, we'll take the shape of
the image and we'll recolor it
to be whatever the
Tint Color is.
And the great thing
about Template Images is
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that they can be recolored
to match the rest of the UI
as the Tint Color changes.
However, sometimes
you'll want to opt out
and to let you control this
behavior we have a new property
on UIImage called Rendering
Mode lets you control whether an
image is treated as an
original image and shown
in its full colors or
whether it's treated
as a template image.
Here are the three different
values for Image Rendering Mode
and we'll use our star
image as an example.
Now, the important thing about
how images are rendered is
that it depends on what
context they're used in.
So, we'll talk about
an ImageView
and also a BarButtonItem like
the one in our Navigation Bar.
The Automatic Image
Rendering Mode means
to render the image
either as a template image
or an original image depending
on the context its used in.
So, in our ImageView the
image will just be treated
as its original normal form
and shown with its colors,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
but because a BarButtonItem
defaults to showing it
as a template image it'll be
used as a template image there.
With the AlwaysOriginal
Rendering Mode the image will
always be treated exactly
in its original form
and we won't touch
any of the pixels.
With the AlwaysTemplate
Rendering Mode we'll always
treat it as a template image
and it will always be recolored.
So, you can think of the
Automatic Rendering Mode
as saying you figure out
what to do with my image.
And the AlwaysOriginal and
AlwaysTemplate Rendering Modes
as saying I want full control
and this is what I'm specifying
as a behavior for
this particular image.
So, now let's go back
to our Navigation Bar
and see how that applies.
When we create our image, in
this case using image names,
it's returned with the Automatic
Rendering Mode by default.
And again, this means
to do the default
for the context it's used in
and that's why our image
is getting recolored to red
when we use it in
a BarButtonItem.
So, all we need to do is use
the Imagerendering Mode method
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
on the image that we have
and now we'll convert
the ImagesRenderingMode
into whatever we've specified.
So, since we're passing an
AlwaysOriginal our image now
becomes an original image
and it's shown in full color
in the Navigation Bar.
Now, this same behavior
applies to the Tab Bars
and the Tab Bar items
that shown within them.
Here, by default an image
that you set will be recolored
to the Tint Color when the
Tab Bar items is collected
and it will be colored gray
when the item is uncollected.
We used to have a method
called, Set Finished Image
with Finished Unselected Image.
And that allowed you to
set images that were used
for this selected
and unselected state
and it wouldn't be recolored.
So, this method was
actually doing two completely
separate things.
One of them was specifying
that the images
that you set should
not be recolored
and the other was
setting different selected
and unselected images.
So, we've actually
deprecated this method in iOS 7
and you can now do either of
these two things separately or,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of course, combine
them together.
You can use the AlwaysOriginal
Rendering Mode to specify
that the image you set
should not be recolored
and this was the finished
part of the old method.
And you can use the Image
and SelectedImage properties
that we talked about earlier
to set images that are separate
for the unselected
and selected states.
And, of course, you can use
either of these separately
or combine them together
to get exactly the
effect that you want.
So, in the profile view
of our application we show
that segmented control and
this left the user to choose
to be Xs or Os in our game.
And we're just using a standard
UISegmentedControl here.
But we'd like to customize
it a little to better fit
with our applications.
So, first of we'll set a
custom background image
for the Segmented Control and
notice that the background image
that we set is not
getting recolored along
with the Tint Color.
That's because Segmented
Controls default
to treating their background
images as original images.
So, they won't be
recolored and, of course,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
you can use the AlwaysTemplate
Rendering Mode if you want
to opt back on into
that behavior.
Now the foreground images the
X and the O on the other hand,
they're being recolored
because they're getting treated
as Template images.
So, to opt them out of that
we can use the same image
with Rendering Mode
Method and pass
in the AlwaysOriginal
Rendering Mode.
And we'll use that here because
in our application Xs are always
red and Os are always green.
So, we want them to keep
their original colors.
Now, Steppers and System buttons
have actually the same behavior
we just talked about
for Segmented Control.
The thing to remember is
that foreground images
that you set default to
being Template Images
and background images default
to being Original Images.
Everywhere else in UIKit
that we use images defaults
to treating them
as original images.
This includes things like
Image Used and the images
that you set in Table
View Cells.
So, if you look here in this
section, the Statistics section
of our Profile view, you'll see
that when we set those images
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
on our Table View Cells
they look kind of plain
because they're being--
they're just original images
so they're just shown in
their original color and we'd
like to better match with
the rest of our application
by making them recolorized
to match the Tint Color.
So, to do that we'll
use the same Image
with Rendering Mode Method
and this time we'll convert
them to Template Images.
And this way they'll
match the Tint Color
and they'll change along with
the rest of the application.
So, this is a great technique
to consider if you want
to add some color and match--
better match with the
rest of your application
as it changes color
and it saturates.
So, let's talk about Status Bar,
the Status Bar a
little bit more.
The change to the Status Bar to
make it always transparent means
that it's really important
that your application applies
exactly the right background
behind the Status Bar.
And as I said earlier,
it's the View Controller
that provides that.
Well, traditionally in iOS
the Status Bar was actually
controlled by UI
Applications properties
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
where you set the
style and hiddenness.
And this made it very
easy for different places
in your application to set this
Status Bar style and to stomp
on the value that
someone else had set.
In iOS 7 we want to make it
really easy for View Controllers
to control exactly
the Status Bar style
that matches the background
that they've shown.
So, we're introducing a
new system to allow you
to control the Status
Bar's appearance.
The way this works is in your
View Controller you can override
either of these two methods
to specify whether you want the
Status Bar to be hidden or not
and what style you want it to
be shown as when its visible.
And when you're using this
new system the UIApplication
methods to set the Status Bar
style won't do anything anymore.
Instead we'll find the
current View Controller that's
underneath the Status Bar
and we'll ask it what kind
of Status Bar style it wants.
So, this allows your View
Controller to make sure
that its background and
its Status Bar match.
And actually the
values that you return
from these two methods don't
have to be static values either.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
You can change them over
time, but the important thing
with changing them is that
after you make a change you have
to call setNeedsStatusBar
AppearanceUpdate
on the View Controller that's
changed and this lets us know
to update the Status
Bar to match the changes
that you've just applied.
And then we'll redisplay
the Status Bar just
as you specified.
And these Status Bar
changes apply actually
to container View
Controllers as well.
So, all of our standard UIKit
Container View Controllers
like Tab Bar controllers
and Navigation Controllers
will implement this
for you automatically.
So, they'll automatically
forward control
of the Status Bar to
whichever View Controller
within them is underneath
the area of the Status Bar.
And you can implement
this in your own container
of View Controllers as well.
It's actually very easy.
There's another two
methods that you implement
in your Container View
Controller to return
which of its children
should be used
for determining what the Status
Bar should use for its style
or for its hiddenness.
And once again whenever you
change the value return from one
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of these you can-- you need
to call the same method,
setNeedStatusBar
AppearanceUpdates to let us know
that the state of your View
Controller has changed.
Now, this change to how
the Status Bar is set
up is a very big
change and it's global
to your entire application.
So your application will either
use entirely the new system
or entirely the old system.
And we have a global
switch that you can use
to specify which system to use.
It's an info.plist key
called UIViewControllerbase
StatusBarAppearance.
And you can set it
to yes or no to opt
into the new system
or remain out of it.
We've used that- we've
opted it into the system
in our sample application
and in most
of our View Controllers
we haven't had
to override the default
values of the two methods.
But one place that we are using
them is in our Game view here.
This view defaults to
showing a white background
but when the game is over it'll
actually invert the background
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to be black and so it will
invert the Status Bar to match
that change, like this.
And this is really easy to do.
You just have to implement
two pieces of code.
First, override
preferredStatusBarStyle
and then we'll check if
the game is finished or not
and return either light
content if it's over or default
if it's still in
progress and then
when our game state
changes we just call
needStatusBarAppearanceUpdate,
as I mentioned earlier.
However, there's one
special thing here,
which is that we've
put this call
to update the appearance
inside of an animation block.
And when you do this we'll
automatically animate the Status
Bar Appearance change to
match the same animation
as the block that
it's inside of.
So, we can animate along with
our background color change
and they'll both fit
together perfectly.
So, let's take a look at
that again in slow motion.
Great, alright now let's talk
about how you can
create Custom Controls.
We worked really hard
on the UIKit Controls
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to make sure they
always work great.
And I'd like to show you how
you can make your own Custom
Controls work just as well.
However, before you start making
the Custom Control you should
always consider whether
there's a standard UIKit Control
that you can use in customized
to work the way that you'd like.
So, in our Profile view we had a
really Custom Segmented Control
but we were able to customize
it just by using images
and rendering modes to get
the appearance that we wanted.
If you use Standard Controls
then you will automatically get
consistency for your users and
it'll be less work for you.
This is always something
to check before you start.
Now the first Custom Control
in our application is this
Rating Control that's shown
at the top of the
Game History view.
This is a pretty simple control
that lets you set a rating,
a number of stars for previous
games that you've played.
And to tell you how we built
this Custom Control I'd
like to tell you a little secret
about how we make
our UIKit Controls.
When we create a control
like this UIButton in iOS 7,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
we don't actually start
with a blank slate.
Instead, we use other existing
standard UIViews as pieces,
building blocks to put
together these controls.
So a button consists of
Image Views and UILabels.
And when we do that it
automatically gives us the great
Text Rendering support
from UILabel
and it also gives us
support for all of UIImage
like Rendering Modes
and Resizable Images
in the UIImage View.
Similarly steppers
actually consist
of an Image View
and two buttons.
And this gives us not only
its appearance but also a lot
of interactivity for free.
So, we've taken the same
approach in our Custom Control
and here we're using an image
view to draw the background
and we're using five
different buttons
to draw the foreground content.
In fact, with button it's
even easier for us here
because we can set different
selected and unselected images
for the button and to toggle
between them we can just
set the Selective Properties
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of our buttons.
Now, an important thing that we
had to do here when we wanted
to use buttons inside
of our custom control is
to use the UIButton
type Custom.
And when you use a Custom type
button this opts you out of all
of the standard system
animations and appearances
so that you can fully
customize the button to look
like exactly what you want.
One other thing you
can do if you want
to customize your
button even further is
to subclass the UIButton and
override these three methods.
This lets you exactly control
the positioning of the images
and the text that's
shown in the button
so you can get exactly
the effect that you want.
So, now let's take a closer look
at the background that we show.
As I mentioned earlier, it's
an image that's being shown
in an ImageView and we're
actually dynamically creating
this image at runtime,
which is really easy to do
with the UIGraphics
function that allows you
to create a new image context,
draw into it and then pull
out an image from the context.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, we're using UI [Inaudible]
path to do our drawings here
and one thing you will
notice in iOS 7 is
that UI [Inaudible] path has a
new, draws rounded rectangles
in a new way in iOS 7, a bit
smoother and more continuous.
So you'll get better curves
for your [Inaudible]
paths automatically
by using UI [Inaudible] path.
Once we have our dynamic image
we just set it on the ImageView.
However, we'd like
this background image
to follow the Tint Color
of the application.
And that's really easy to do.
Just like before we'll set the
Rendering Mode of the image
by calling
ImagewithRenderingMode
after we've dynamically
created the image
and passing in AlwaysTemplate.
And we can actually combine
the Rendering Mode call
with Resizable Image calls.
So after we change
that Rendering Mode
of our image we'll pass that
Resizable Image with Cap Insets
to make it both a template
image and a Resizable Image.
And this way our-- we can use
this same background image
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
in all of our ratings controls
and no matter what size
that they're shown as, so we
can just reuse that one image.
No another way that we got
a lot of the functionality
of our Ratings Control for free
is by subclassing UIControl.
When you do that you'll
automatically be able
to participate in the Target
Action System the UIControl
Implements and, in fact, UI
Control will even send all
of the touch related action
methods for you automatically.
However we'd like to go even
further with our Rating Control
because we also have
a value associated
with the control
which is its rating.
So, here when a user
touches a button,
after we set the rating we'll
also send all target action
events for the Value
Changed UI Control Event.
In this way we can use
Value Changed Events
in our View Controller to add
ourself, the View Controller
as a target and the
Change Rating Method
on our View Controller will
automatically get called
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
whenever the user changes
the rating of the control.
So, the next view that we have,
Custom View in our
application is Account View.
In our Profile we show you
here the number of victories
and defeats that you have
and to make things a little
more fun we'll show them
as tally marks here.
So, we're doing this
just by overriding UIView
and by implementing
our own draw drawRect
because this is a
pretty simple to draw
and it's one single
continuous region.
In our drawRect we're actually
using our current Tint Color
which allows us-- which we can
set on the graphics context
and then do any drawing
that we do normally.
So, the Inherited Tint Color
that's returned is actually
guaranteed to always be nil
because it'll inherit
its superview
if the Specific Tint
Color of the view is nil
and it'll use the
system default color
if it doesn't have a superview.
So, we can always rely on the
tint color to be a real color
that we can use to draw with.
However, there's one last
thing that you need to know
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
about Tint Color and that's how
to update it when it changes.
Whenever the Tint Color changes
we automatically call the
tintColorDidChange method
on all of your views.
This is a new method that kind
of behaves as a notification
to your view to tell it needs
to update anything that it has
that was using old Tint Color.
So, if we look at changing the
Tint Color of the window to red
after the Inherited
Tint Color changes
that tintColorDidChange
fires to that view
and the same thing happens for
the subviews and their subviews.
So, everything in the window
will automatically get a
tintColorDidChange
notification either
when its own Tint Color changes
or when its Inherited
Tint Color changes due
to changes in superview.
And the same thing happens
automatically for you
when the TintAdjustmentMode
changes for your view.
So again, if we set the window
to be dimmed its Inherited
Tint Color will change to gray
and tintColorDidChange will
be called both on the window
and all of its subviews
and their subviews
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
as their Tint Colors
change as well.
So, going back to
our Count view,
all we need to do is
override tintColorDidChange
and then we'll just tell our
view that it needs to redraw
by calling setNeedstoSite.
Of course, in our Count
view we're using setNeedsto
[Inaudible] so that we only have
to redraw the part of our view
that uses the Tint Color itself.
Now another place that
we'd like to use Tint Color
in our application is
in this Table View Cell.
Here we use the Tint Color as
the detail labels text color
and this will help emphasize
the result of previous games.
Once again, we use
tintColorDidChange
and this implementation will
actually take the Tint Color
of our current view and set it
as the Text Color
of our detail label.
And this will make our detail
label match the Tint Color
and also automatically update
as the Tint Color changes
or becomes desaturated.
So, there's one last really
important thing to consider
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
when you're implementing
Custom Controls
and that's Accessibility.
It's really important to
implement accessibility
in your apps and in your
Custom Controls so that all
of your users can really
enjoy using your applications.
It's also really easy to do.
So, if we look at our Ratings
Control it acts as kind
of a container for the
buttons that are inside of it.
So, we'll return No for
is accessibility element
of the control itself.
And that will cause the
accessibility system to look
for the subviews of the
control and treat them
as accessibility elements.
UIButton implements
a lot of accessibility
for us automatically
so all we need
to provide is an
Accessibility Label
for our button, for out buttons.
And Accessibility Label
is essentially text
that describes what the
button is behaving as.
So, we'll just use the number of
stars as the Accessibility Label
for our button and, of course,
we used a localized string
so that they'll automatically
be translated
as we translate our application
into other languages.
Now our other custom
control is this Count view
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and we'll also need to
add Accessibility here.
In this case since the view
is just a single element we'll
return Yes for its
Accessibility element and then
that top level view
we'll be treated
as an Accessibility element.
We'll also need to return what
kind of traits that it has.
In this case we're
essentially saying
that our Count view is
similar to an image,
so we'll turn that as its trait.
And finally, we'll need to
return an Accessibility label
that has text that described
what that view represents.
Since our Count view is
essentially representing a
number, we'll return a text
version of that number.
Alright, so now we've fully
customized our application
and let's take a look
at what it looks now.
So, here's our new
customized application.
We'll start in the Game view
and here we can just tap
to play our pieces
and you'll notice
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that when the game finishes we
automatically transition the
background slack and
the Status Bar to match.
[ Applause ]
>> Also, when I pause
the game you'll notice
that our Pause button gets
the selected appearance
because we're using a System
button and you'll notice
that in our Tab Bar we
have different images
for the selected and
unselected states.
Next, let's take a
look at messages.
When we create a new message,
notice that the composed
image gets desaturated
in the background but the Cancel
and Post buttons
remain fully saturated.
And after we post a
message we can select it
and make it a favorite image
which we'll use our
AlwaysOriginal favorite
star image.
You can also see here a
System button that we've used
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
where we haven't set
the Rendering Mode
and here our image
is getting recolored.
In the Profile view you can
see our Segmenting Control
where we customized
the different images
and Rendering Modes and as
we change what piece we want
to use you'll see that we're
changing the Tint Color as well,
which causes all of our
Image views to update,
our Custom subview
and the Tab Bar.
Finally, in the History view
you can see our Table View Cells
which use the Tint Color for
their detail label and inside
of one of the History views
you can see previous games
and also our Rating Control
including its background,
which automatically
matches the Tint Color.
And finally, you can see
our Custom Back Indicator.
Great, so that's our
customized application.
[ Applause ]
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
>> So, today I've showed
you some of what's changed
for Customization in iOS
7, a few advance topics
like Tint Color and Image
Rendering Mode and finally,
we saw how to use your
own Custom Controls
to extend your application
even further.
So, I hope that you all go
out and use these techniques
to make your applications
really great.
Thank you.
[ Applause ]
[ Silence ]