WWDC2015 Session 222

Transcript

X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
[ Applause ]
>> SARA RADI: Good
afternoon, everyone!
Welcome to the new UIKit support
for international user
interfaces session,
my name is Sara Radi I'm a
international utilization
software engineer, and
I'm one of those people
who would really love
to use your amazing app
in my native language, but
I just can't find great apps
in the App Store localized.
My native language is Arabic.
And I grew up in a country,
where we didn't write
right from right to left.
And before Smart Phones became
so popular, we didn't have
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And before Smart Phones became
so popular, we didn't have
to think about layout
in right to left.
So basically just
supporting the text rendering
and the font was enough.
However, today, with all of
these electronic devices,
people are using
more and more eBooks,
and they are interacting more
and more with their devices.
So supporting just the text
in your apps is not enough
and it becomes very important
to think about the layout
and the flow of your app when
supporting these localizations.
And just like me, there are
a million of users who wants
to use their apps in
their native language.
This is a huge opportunity
for you to grow your markets
in these areas of the world.
This is an example of an
Apple ad in Dubai in one
of the largest buildings
in the world,
and this gives you an idea
of Apple's presence
in the Middle East.
So what are we going
to talk about today?
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So what are we going
to talk about today?
So mainly we are going
to focus -- I'm sorry.
Mainly we are going to focus
on right-to-left user
interface challenges,
and then we are going to
introduce the new UIKit support.
We added the native
UIKit support
for right-to-left languages so
we made it seize easy for you
to support right-to-left
with no effort.
And then we are going to
talk about your custom layout
and how can you add
right-to-left support
in your custom layout with auto
layout, and then we are going
to introduce new APIs that we
just added on iOS 9 and talk
about exception cases
and hopefully by the end
of the session, I want to see
more apps localized in Arabic
in the App Store, and Hebrew.
I'm sorry.
So let's get started
with an overview.
So when you are designing your
app in left-to-right languages
or in English, for
example, you always start
by placing the most
important elements
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
by placing the most
important elements
on the left side of the screen.
And then you if have,
like other elements,
so they would flow
naturally left to right.
And the reason why we do that,
is because the layout itself it
starts to, [follow] the reading
and the writing direction
of the script.
So it makes total sense if you
are designing your app in right
to left, to flip the layout and
this is because the scripts read
and write from right to left.
And the UI mirroring
concept does not only apply
to static UI.
It also applies to dynamic UI.
For example, in your app,
if you have navigation
gestures and animations.
For example, so here the
back button is always
on the left side of the screen.
So when writing
in a right-to-left environment
not only the back button should
be on the right side,
but also the gesture
and the animation
that comes with it.
So what's new in UIKit.
So on iOS 9 UIKit sender
controls fully support user
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So on iOS 9 UIKit sender
controls fully support user
interface mirroring.
Which means when
your apps are running
in right-to-left localizations
they will flip automatically
for you.
Also the whole system and all
our native apps fully support
right-to-left UI so your
apps should be consistent.
So let's go through
some standard controls
in our native apps.
Let's start with UI table view.
So this is an example
from the Settings app,
where we are using a
stock UI table view.
As you can see here we are
running the device in English,
so the icons are on the
left side of the screen,
the labels are left aligned, and
the table view accessories are
on the right side, so
changing my language to Hebrew,
for example, will flip the table
view cells automatically for me
so all of the icons now
are on the right side.
The text labels are right
aligned on left of the icons,
and the table accessories
are on the left side.
Next navigation controller.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Next navigation controller.
And this is an example
from the phone app
where you can see the back
button now is on the right side
of the screen and also
the navigation gesture
and animation comes from the
right edge of the screen.
If you look closely,
also the UI table,
the UI tab at the
bottom also flips
so now favorite is
on the right side.
Next, tracking gestures,
this is another example
of a UI table view in the clock
app where you can see the slide,
the swipe to the lead
gesture is coming
from the left edge
of the screen.
If you use a stock UI table
view and enable the swipe
to the lead gesture --
that comes for free.
So, how can you enable
right-to-left support
in your apps?
If you already have this
localizations in your app,
all you need to do
is link against iOS 9
and test your apps, make sure
that your custom layout
works as expected.
However, if you are
adding this localizations
for the first time,
so we recommend
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
for the first time,
so we recommend
that you move your
storyboards to base approach
with auto layout and when
you add the localizations,
XCode with create basically
strings fast for you
so you can export them,
send them to translations.
When you get them back, you
can import them via XCode again
and when you run your app
at run time, you will see
that your translation is
integrated automatically as well
as your layout is flipped.
So now let's talk about testing.
So XCode makes it so easy for
you to test right-to-left layout
without even having
the localizations
or integrating the translations.
So if you go to XCode scheme
and you change your application
language from system language
to right-to-left to do language,
that will simulate a
right-to-left environment
for you and you will have
an idea if your app is ready
to ship or not with
right to left.
And to show you, all what
we just talked about now.
I am going to call my
colleague Aaltan Ahmad
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I am going to call my
colleague Aaltan Ahmad
on stage to give you a demo.
>> AALTAN AHMAD:
Great, thank you, Sara.
I am going to show you an
example of an app that I wrote,
a simple recipes app
that I wrote that I want
to add a right-to-left
localization for
and I will show you
how easy that can be
with the new stuff we
have added to iOS 9.
Here is the app.
It's pretty straight forward.
There is a table view,
a tab bar at the bottom.
If we tap one of the
cells we get taken
to the details view
for the recipe.
Here we have some custom
labels and stuff like that laid
out using auto layout
and a collection view
to show off some pictures of
the recipe that the user is
about to make hopefully.
So now that we are ready to add
a right-to-left localization
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So now that we are ready to add
a right-to-left localization
to our app we actually want to
see what it looks like first,
before even integrating any of
the translations, or doing any
of that work, we want to
see what our app looks
like with the new
changes we have added.
To do that as Sara mentioned I
will go to the edit screen menu
in XCode and from the
application language drop-down,
will select right-to-left
pseudolanguage.
This basically has the effect
of bringing in those UI changes
without loading any
of the translations.
And it has the added bonus
of if I'm not a native
right-to-left language speaker I
can see my app in English
with the right-to-left UI
and not need to learn
those languages
or have a native review
before I do any translations.
So I'm going to close that
and I will run the app again.
That's it.
So without writing a single line
of code, I have introduced all
of these changes into
my app and I can see
that things look great.
So let's go through our app
and see what changes we got.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So let's go through our app
and see what changes we got.
So because I was using a
standard table view cell type,
I, the text label is
over on the right side.
The Chevron is on the left
side and points to the left.
Even the tab bar at
the bottom is flipped.
So the first tab is now
on the right-most side
as a right-to-left
user would expect.
If you look at the navigation
bar, the navigation button
that was on the right side
is it now flipped over.
And if I tap on one
of the cells,
I can see that because
I was using auto layout,
with leading-to-trailing
constraints,
that entire UI is flipped
along with the text alignments.
The cool thing here to notice
is that the collection view --
because I was using a
stock collection view
with the default collection view
flow layout -- has also flipped.
So the first picture is
now on the right side
and the subsequent items
follow to the left.
As Sara pointed out, the
navigation is also reversed.
If I click this back button,
you can see it takes me,
the navigation comes over from
the right edge, and in fact,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
the navigation comes over from
the right edge, and in fact,
if we try to swipe, we
see the same effect.
So, great.
I have checked out my app with
these new right-to-left changes
and I have seen it looks
great and I'm ready
to add the translations.
So let's add the translations
and see what the
process looks like.
So, I am going to
select my project,
in the project navigator, I
will head to the editor men,
and here you can see there
is a few localization-related
options, so I will go
to add localization
and I will pick Arabic.
So XCode presents me with a
dialogue and it does its thing.
This basically creates the
localizable resource files
that I need to have translated.
The next step is to
actually export the strings
from my project, so we go
back to the editor menu
and hit export for localization.
XCode asks me where
I want to do that.
I select the desk
top, and hit save.
XCode has now taken the all of
the strings from my project,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
XCode has now taken the all of
the strings from my project,
packaged them up
into an XLIFF file
which is a common file format
for software translations,
and put that file on my desktop.
I can take that file and send
it to a translator, who will go
and make the correct
translations for me
and send me back a
translated XLIFF file.
So very sweet, the
translator, they do the work.
I'm ready to import
the localizations,
I go back to editor,
import localizations,
go to my translated XLIFF
folder, and here is my Arabic
or XLIFF with the
translations, hit Enter.
XCode goes and takes all
of those translations
and integrates them
into my project.
And now we have both the UI, and
the translations ready to go.
So final step, I'm going to go
back to the edit scheme menu,
and this time instead
of right-to-left pseudolanguage
I will select Arabic,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
which shows up because I
wrote the localization.
Close. Run the app again.
So there you have it.
Now, I have my translated
strings,
my navigation controller
title is translated.
My tab bar items are also
translated into Arabic
as the user would
expect, and I'm able
to offer a complete
right-to-left user experience
for my Arabic-speaking
customers,
and in fact the bonus
item here is
because I was using date
component formatters
to format my prep time
and cook time durations,
I actually get localized
versions of those as well.
So shameless plug for using
number and date formatters.
And that's it.
That's how easy it can
be to bring your app,
your existing right-to-left--
, existing left-to-right apps
over to right-to-left.
To talk to you a little bit more
about how you can bring
your custom UI over,
I will hand it over to Paul.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I will hand it over to Paul.
[ Applause ]
>> PAUL BOROKHOV: So as you
just saw from Sara and Aaltan,
if you are using stock UIKit
controls it is very easy for you
to add a right-to-left
localization
to your application.
But what if you have something
a little bit more complex?
First, before we jump in, I just
want to go over some API changes
that we have made, if you
are customizing UI controls,
that make it easier for you
to support right-to-left
localizations.
If you are using UI text
fields, left view, right view,
left view mode and left view
mode are automatically mirrored
for you in right to left, so you
don't need to do anything else.
The only thing to be aware of
is that rect for bounds methods,
they'll stay unchanged.
For table views if you are
setting separatorInsets,
the left and right measurements
will automatically be flipped
for you, with no
additional work on your part.
If you are using a
slider, the minimum
and maximum value images are
automatically flipped for you,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and maximum value images are
automatically flipped for you,
because in a right-to-left
context,
the minimum of a
slider is on the right.
The only thing you need to
be aware of is that the rect
for bounds methods,
while they are flipped,
if you are customizing
the offsets on the x-axis,
you'll need to make sure
those are properly accounting
for right to left, if you
are running in that context.
And finally for a navigation
bar like you saw in the demo,
we are flipping left bar button
items and right bar button items
for you automatically, but if
you are adding subviews outside
of those APIs, you
will want to make sure
that those are properly
positioned,
as otherwise you are going
to have overlapping content.
So let's talk about some
different types of custom UI
that you might have on
your application and how
to handle those correctly.
So like you saw earlier,
standard cell types will flip
for you automatically with
no additional work needed.
What that means is that,
if you have custom layouts,
you will want to make sure
those are flipped as well,
to be consistent with
the rest of the OS,
as well as potentially,
other table view cell types
in your own application.
You can of course do this by
simply mirroring the frames
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
You can of course do this by
simply mirroring the frames
in your layout, but the
recommendation that we give is
that you simply use
auto layout with leading
and trailing constraints because
this requires no additional work
on your part, and you can
have the exact same interface
and code handling both left
to right and right to left.
The story is quite similar
for collection views.
So, like we saw in the demo,
collection vew flow layout
automatically supports right
to left and just
reorders the items
to flow from right to left.
What that means if that
if you are doing a custom
collection view layout you will
want to make sure it's properly
flipped on the x-axis as well.
Generally, what we recommend
today is you subclass collection
view flow layout instead
of writing your own
layout code from scratch.
And there is actually a session
that will happen tomorrow
in the afternoon that talks
about how to do this well,
as well as other
customizations you may want
to do in Cocoa Touch.
Now, we have said the
word auto layout a lot
of times already
throughout this presentation,
but maybe you are not
familiar with this technology.
So Auto Layout is a way to
position elements in your UI,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So Auto Layout is a way to
position elements in your UI,
instead of using frames,
using a set of constraints.
It's been available since iOS 6
it makes it much easier for you
to support different screen
sizes both iPhone and iPad,
as well as different
size classes.
With the new split-view
multitasking,
it makes it that much easier to
make your application compatible
with this new technology.
Finally, even before
right to left,
Auto Layout makes
it easier for you
to support additional
localizations
because once you have a
good set of constraints,
adding a new localization
is just a matter
of translating strings,
and you don't need
to write any special code to
properly handle the layout.
If these are the constraints
that I have in XCode,
it looks exactly the same
in English, of course.
When I'm running in Russian
is might look like this,
and if I go and decide
to add a localization
for a language that's double
the length of the English one,
I don't need to do
anything extra,
because the constraints
are handling all
of the positioning
of the UI for me.
Today there is one more
reason for right to left.
Now, your layout will also
just automatically flip,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Now, your layout will also
just automatically flip,
and you don't need
to do anything extra.
Now, you can use auto
layout both in storyboards,
as well as in code, as well
as a combination of the two.
So you can have outlets to your
constraints and storyboard,
and then manipulate them
programmatically when you need
to change your UI
for some reason.
So we have talked about
leading and trailing.
Again, maybe this is something
you are not familiar with.
Basically if you have
two labels side by side
and you have horizontal
constrains
between them you can specify
them either as left to right
or leading to trailing.
The difference is that
left to right stays left
to right all of the time.
Leading to trailing on the other
hand, looks like left to right
in a left to right localization,
but it will actually
mirror your UI and layout
in a right-to-left localization.
If you are creating
constraints in storyboards,
when you create horizontal
constraints by the default,
they will already be
leading to trailing
so you don't need
to do anything else.
Similarly if you are
creating constraints in code
and you are using the
visual format language,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and you are using the
visual format language,
there again the default for
horizontal constraints is going
to be leading to trailing.
However, if you are creating
constraints explicitly,
or using the new layout
anchors API in iOS 9,
there you will want to make sure
that you are selecting
the correct attribute
when you are creating
your constraints.
Animations, as you saw in the
demos, are flipped for all
of the stock controls.
What that means is that if
you have custom animation
in your UI, you will want
to make sure that's
properly flipped as well.
Again, of course, you can
use frames if you want,
but the recommendation that we
have is that you use Auto Layout
with leading and trailing
constraints instead,
and simply change the constant
value of those constraints,
which will automatically do
the right thing for both left
to right and right to left
without requiring
any additional code.
Here is an example of
how this would look.
Let's say I want to
change the constant value
of one of my constraints.
I have a duration here.
I will change the offset
to a different value.
Before doing the animation,
I call layoutIfNeeded,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Before doing the animation,
I call layoutIfNeeded,
to make sure that the frames are
in the correct position
to begin with.
Then I call an implicit
animation block,
inside which I change
the actual constant value
of the constraint, and
call layoutIfNeeded again.
This will update the frames
and because it's inside the
implicit animation block,
it will also animate
that change.
You will notice here that there
is no special casing for right
to left, or left to right,
it's just a single set of code
that works perfectly
in both contexts.
Now, let's talk about gestures.
Now, like you saw again for
table views and for navigation,
we flip the standard gestures.
However, the gesture recognizer
API itself remains unchanged.
The reason for that is
because gesture recognizers
on their own are
fairly abstract,
and at the framework
level, we have no way
of knowing what your using
the gesture recognizer for.
So what that means for you as a
developer, is that you just need
to be aware of when you are
using gesture recognizers,
and when you are
responding to gesture events,
what you are actually
using them for.
So, for example, if you are
using your gesture recognizer
to draw on the screen, you
will want to keep that as is
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to draw on the screen, you
will want to keep that as is
because speakers
of right-to-left languages
don't draw backwards.
However, if you have a
custom gesture recognizer
for your table view cells,
for example, you will want
to make sure you flip
that because the layout
of the table view style
has been flipped as well.
Similarly if you are
using navigation gestures,
you will want to flip those,
since like we saw earlier,
back and forward are
actually reversed.
The main thing to
remember here is
that no matter what you are
doing you will want to make sure
that the gesture tracks the UI
that's under it appropriately,
and you don't get a situation
where you are swiping from left
to right but the UI
moves from right to left,
because that would
be very confusing.
If you use Auto Layout this
will make your job much easier.
I would like now to invite
Aaltan back up on stage
to give you a demo of the stuff
that we just talked about.
[ Applause ]
>> AALTAN AHMAD: Thanks, Paul.
So while Paul was talking,
I thought a little bit
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So while Paul was talking,
I thought a little bit
about my app and I
decided that I wanted
to add some more custom UI.
So I went ahead and created
a cool custom table view cell
subclass that I laid
out using Auto Layout.
It's pretty straight forward.
There is some more informative
text labels in the row
and there's a nice image so
the user can see a picture
of what they are about to cook.
There is also this cool little
favorites view on the left side
that the user can drag out
by swiping across the cell,
similar to the stock
swipeToDelete gesture
that we have on table
view cells right now.
If they pull far enough, a
little star appears on top
of the image in order
to show them
that they favorited this recipe.
So let's look at what this looks
like in left to right,
in English.
So, great, my app looks
like lot more vibrant
and inviting right now,
so there is a picture,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and inviting right now,
so there is a picture,
there's some more text labels,
and in fact, if I pull the cell
out far enough, the
favorite view is revealed,
and if I complete the gesture,
the little star shows up.
Great. And while Paul was
also talking I had a chance
to learn the entire
Hebrew language
and add a Hebrew
localization to my app as well,
so for this demo we are
going to be running in Hebrew
as our right-to-left language.
So I will go back to
the edit scheme menu,
and this time select Hebrew,
hit enter and run the app.
Wow! It's because I was using
auto layout with leading
and trailing constraints,
everything just flips.
The image is now over
on the right side.
The text labels are
all right-aligned
in the correct position.
The Chevron, of course, is
stock so that stays where it is,
and again, formatters
plug, my durations
and numbers are correctly
localized for Hebrew.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and numbers are correctly
localized for Hebrew.
But we didn't look
at the custom gesture
yet so let's check that out.
Because the entire cell is
laid out from right to left,
the user is also expecting that
the swipe for favorites will be
in that direction as well,
and more so because the swipe
to delete gesture
system-wide, is flipped.
So they are going to
know that that comes
over from the left edge
and whatever your custom
gesture was they are going
to be expecting it
from the right.
So let's swipe in that
direction and see what happens
for a right-to-left
user in that case.
And you can see that things
don't work as expected.
I swiped, but instead
of revealing that view,
the table view cell
thought I was tapping on it,
and instead presented
the details view.
It doesn't make too much sense.
And the reason this
is happening is
because there is an implicit
assumption in my code,
off the directionality
of that swipe.
I'm expecting the swipe
to go from left to right.
Or, in other words, in
a positive X direction.
In fact, if I go and
swipe in that direction,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
In fact, if I go and
swipe in that direction,
you can see that the
view does reveal itself.
However, it reveals itself
in the direction opposite
to the direction that
I'm dragging my finger,
and that doesn't really
make any sense to the user.
And you really want to
avoid situations like this.
So let's jump into the table
view cell subclass and see
if we can figure out
what's going on here.
So here you can see
I have two gesture
recognizer-related methods.
So the first is this gesture
recognizer should begin method.
And the reason I have
to implement this is
because like I said,
I want to support both
that custom gesture, as well
as a stock table view gesture.
What goes on here if the
user swipes in the direction
of my gesture, I allow my
gesture recognizer to begin,
and if they swipe in the
direction of the swipeToDelete,
I don't do anything and I let
table view handle that stuff.
So right here you can see
I have the X translation
of the gesture recognizer and
if that translation is greater
than zero, or left
to right, I go ahead
and begin my gesture recognizer.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and begin my gesture recognizer.
So what we really need to do
here, is check if we are running
in a right-to-left localization,
and if we are, we need to look
for translation in the
opposite direction.
In order to figure out whether
I'm running in a localization
in a right-to-left localization
or not, I will use new API
that we added in iOS that
Paul is actually going to talk
about shortly, but since it's
exactly what we need right now,
I will go ahead and use it.
So I will declare a new constant
called isLeftToRightLayout
And I'm going to use a new
user interface layout direction
for semantic content attribute,
API, that we added in iOS 9
and I am going to parse in my
view semantic content attribute.
This returns the resolved
layout direction, left to right
or right to left for this view,
and if that direction comes back
as left to right,
I know I'm running
in a left-to-right localization.
So next step before
checking that translation,
I will look at my
isLeftToRight variable.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I will look at my
isLeftToRight variable.
If it's left to right,
we continue as usual.
If it's right to left, we look
for a translation for less
than zero or in the negative X.
The second method here, is this
updateFavoriteButtonPosition
method.
So here is where we actually
manipulate the constants
of the constraints and
show that view on screen.
Here you can see against I have
should allow dragging favorite
button constant that allows--
that tells the following
code whether it should start
revealing that view, and, again,
similar thing, we are checking
for a positive X translation.
Solution is also similar, we
can just pick up this check,
bring it over here, and check
for the left to right layout,
and check for translation
in the opposite direction,
and right to left.
The last bit over here is
this distancePulled variable.
So the distancePulled
variable, or constant,
is telling the following code
how far the user has dragged
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
is telling the following code
how far the user has dragged
their finger across the cell.
Now that we can accept a
negative translation it doesn't
really make sense for the
distancePulled variable
to also be negative
because it's conveying sort
of an absolute value, so to
rectify that, we are going
to just take the absolute value
of the translation as well.
That solved that problem for us.
With those few changes
let's run the app again.
And see where that got us.
Okay. Things look
good here still.
Now, if I drag my finger
over, things work as a right
to left user would expect.
So really that's it,
you really just need
to make sure you are
watching out for these kinds
of assumptions in your code,
and really just accommodating
for the right-to-left keys,
which oftentimes turns
out to be something that's
really just that simple.
And that's all it takes to bring
your custom gestures and UI
over to right to left.
To talk to you a little bit
more about some exceptions
and best practices,
back over to Paul.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and best practices,
back over to Paul.
[ Applause ]
>> PAUL BOROKHOV:
Alright, Thanks Aaltan.
So let's talk about
some exceptions and some
of the new API that we
have introduced in iOS 9.
One of the things we saw
in Aaltan's demo was the
semantic content attribute API
so before we get
into that let's talk
about what semantic
content attributes are.
The semantic content attribute
is a new property on UI view,
and it's there to make sure that
all UI looks correct in right
to left and left to right
because in some cases not all
of the UI flips and
we need to make sure
that we have a way
to specify that.
Now, the default
semantic content attribute
is unspecified.
This will flip in a
right-to-left localization
and stay as is in a left
to right localization.
But we have some
additional attribute types
that you can set, that
will prevent the flipping
from happening, for a number of
historical and other reasons,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
from happening, for a number of
historical and other reasons,
but they manage the expectations
of right-to-left users.
Finally, the resolution
of leading
and trailing constraints
is actually based
on the semantic content
attribute.
So that's just something
to keep in mind.
So the first one is playback.
The idea here is if you have
some sort of playback control,
you sub the semantic content
attribute of that control,
or that group of
controls, to be playback,
and that will keep
them left to right.
So you can see here
in the new music app,
we have the progress bar as
well as the playback controls,
they stay left to right.
They do not flip.
The next one is spatial.
This is for annotating controls
that correspond to some sort
of direct UI manipulation
where maybe you have a D pad
in your game and you
press up and it goes up.
You press left, it goes left,
or similarly for text alignment.
So here we have on the pages
app, a segmental control
that lets you set the
alignment of your text.
Left-aligned text will
still stay on the left side,
even when running in a
right-to-left localization,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
even when running in a
right-to-left localization,
so we keep that as is.
Finally, for those of you
who want to be more explicit,
we have these forceLeftToRight
and -RightToLeftand
right-to-left attribute types,
and they just do what you
would expect from the name.
The forceRighToLeft one
will actually affect layout
in a left-to-right localization.
All the others only
have an impact
when you are running
in right to left.
And the only thing that I will
say about these is if you feel
like you want to use them,
please come talk to us
on the lab or post
on the dev forums
to just make sure you
are doing the right thing
and that the existing
API doesn't quite satisfy
your needs.
or maybe we are missing API,
there is another type we need
to add, and you can
tell us that.
I want to talk about some
best practices for UI and text
when you are supporting
right to left.
One of the things you want to
make sure you are doing all
of the time (and like we saw in
the demos) is to use formatters.
For Arabic this is
particularly important
because different Arabic
speaking countries will use
actually use different words
for the months of the year.
So you will want to make sure
that you display those correctly
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So you will want to make sure
that you display those correctly
to all of your users,
no matter what region
or language they are using.
In fact, there is a What's New
in Internationalization talk
tomorrow, bright and early
at 9:00 in the morning, where
they will talk about all
of the existing formatters
as well as some
of the new formatter APIs
that are available in iOS 9.
However, you will want to make
sure that if you have some sort
of layout or logic
branching like we saw
for the gesture recognizer,
you never want to use NSLocale
or NSbundle or NSFormatter
for determining that.
So perhaps you have
seen code like this.
You want to figure
out if you are running
in a right-to-left localization.
You look up the preferred
languages, you pick the top one
and if its writing direction
is right to left, boom!
This is something that you
literally never want to do.
There is many ways
that this can break.
It's just not what
you want to be doing.
If you want to find out that
your application is running
right to left.
Instead, you'll want to use
this new API we saw in the demo.
User interface layout direction
for semantic content attribute,
and pass in the semantic
content attribute of the view
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and pass in the semantic
content attribute of the view
that you are interested
in figuring
out how it's being laid out.
And that will give you either
left to right or right to left
as the UI layout direction.
Of course, the converse is that
you shouldn't be using this
for regional or format settings.
Now, here is a sample that
matches sort of the intent
of the previous slide
but is actually correct.
We get the semantic
attribute of the view,
we ask for the layout direction,
and if that happens to be right
to left, we do custom
logic, perhaps.
Now, when dealing with
text, what you will want
to do is just leave
alignment and directionalty
at their default
values most of the time.
So, new in iOS 9, natural
alignment is now the default
so you don't need to do
anything to have text
that is left-aligned in
left-to-right languages,
and right-aligned, in
right-to-left languages.
Similarly the base writing
direction is something you
should never have to touch
unless you are writing a
text editor.
That has been the
default since iOS 7.
For probably 99% of applications
there is no reason you should
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
For probably 99% of applications
there is no reason you should
ever need to touch this value
and change it from default.
Again, you don't want to use
these for layout code branching.
Instead use the API that we
saw in the previous slide.
Finally, I would like to talk
about images so we have new API
and UI image called
imageflipped for right
to left layout direction.
What this will do is this will
horizontally flip the image
automatically for you when you
are in a right-to-left context.
So an image flipped
for right-to-left layout
direction will stay as is
in left to right, and then
flip in right to left.
This also based on the
semantic content attribute
of the image view that
contains the image
and generally speaking, you
will want to use this only
for directional images
or something
that conveys some sort of UI.
So people who speak
right-to-left languages they
don't look at all their
photos in the mirror.
So if you see errors or
Chevrons in your application,
like for example, we have in
the Safari toolbar, for the back
and forward buttons, you want
to make sure that those flip,
because all
of the directionality concepts
have flipped from right to left.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of the directionality concepts
have flipped from right to left.
Similarly, if you have some
sort of icons that represent UI,
for example, a list,
so in the new maps app
in the transit feature,
we have this icon
that lets you see the list
of steps because that sort
of represents the table
view, and in the table view,
the icons are on the right side.
You can see the icon
has been flipped,
and more subtly we have
also flipped the person
for the walking directions
because if we didn't,
it would look like the person
was just walking off the edge
of the screen, and it
wouldn't really match the rest
of the layout file.
So I would like to invite
Aaltan back up on stage
to give you a quick
demo of that.
[ Applause ]
>> AALTAN AHMAD:
Last demo, I promise.
All right.
So, great!
I just learned a lot about the
new, cool new APIs we added
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I just learned a lot about the
new, cool new APIs we added
and I decided to take
the customization
of my custom table view
cell to the next level,
by adding a custom Chevron
that is indeed a pizza slice,
so the pizza slice will be
directing our users to go
on to the next screen.
And since we are all really
familiar with the right to left
by now, let's run our
app directly in Arabic
without showing you what
it looks like in English,
since we are past that point.
Great. So because I put in that
image view with the pizza slice,
using auto layout and leading
to trailing constraints,
it actually is in
the correct position.
It's over on the left side of
the cell, where a user on right
to left would expect it.
However, clearly you can see
that the pizza slice is pointing
in the wrong direction.
And this is exactly the
kind of directional image
that Paul was talking
about earlier,
that we can use the
image flipping API
in order to rectify.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
in order to rectify.
So let's go back to that
table view cell subclass.
And here you can see I have
my [unintelligible] method
where all of those outlets, all
of my outlets will be loaded
and ready to go, so the
first thing I'm going
to do is get a reference
to my custom Chevron image.
customChevronImageView.image.
Now that I have that,
I'm going to put it back
in the image view, except
with one small change,
which is I'm going to
call the image flip
for right-to-left
layout direction method
on the UI image itself.
And this basically
has the effect
of leaving your image alone in
a left to right localization,
but flipping it horizontally in
a right-to-left localization.
And the important
thing to note here,
is that because the method
does the right thing for you,
you don't need to worry about
gating it around, and is it left
to right or is it right to left
check, as I was doing earlier.
So you can do call this
method with confidence
in any localization,
and you can be sure
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
in any localization,
and you can be sure
that it will do the right thing.
And that's it, that's
all we need to do.
With that change, let's
run the app again.
Pizza perfection.
So our Chevron is
flipped [applause].
Thank you.
Our Chevron is flipped,
our app looks great,
we have the translations,
custom gesture looks beautiful,
and we are ready to go.
That's how easy it can be to
localize your apps right to left
and back to Sara to finish
up the session for you guys.
>> SARA RADI: Thank you
Aaltan for the great demo.
So just to let you know we
will be posting the demo
that Aaltan gave us
today online soon,
so if you missed anything during
the session, please feel free
to download the simple
code and look at it.
So to summarize before closing
the session, keep in mind
when you are designing your
app for right-to-left languages
that natives of these language
expect right-to-left UI,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that natives of these language
expect right-to-left UI,
and this is a perfect
opportunity
with the new native UIKit
support that we add it on iOS 9,
it's a great opportunity for
you to add this localizations.
It takes no effort, and we also
added new APIs that will make it
so easy not only for non-native-
the native developers,
but also for non-native
developers.
And also it's your
opportunity to reach millions
of users and new markets.
And for more information, please
visit our documentation website
at developer.Apple.com
we have documentation
for internationalization
and also for localization
and if you have questions, also
post them in the Dev forums.
We also recommend that you go
and watch these relates
sessions.
I highly recommend
the What's New
in Internationalization tomorrow
at 9:00 a.m. so thank you,
thank you so much for coming
and have a great afternoon!
Thanks!
[ Applause ]