Video hosted by Apple at devstreaming-cdn.apple.com

Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2013-223
$eventId
ID of event: wwdc2013
$eventContentId
ID of session without event part: 223
$eventShortId
Shortened ID of event: wwdc13
$year
Year of session: 2013
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: [2013] [Session 223] Using Fonts...

WWDC13 • Session 223

Using Fonts with Text Kit

Frameworks • iOS • 50:13

Choosing the right fonts and using them effectively are key to engaging your users. Gain a practical understanding of how fonts work in Text Kit, learn best practices for using system-provided and bundled fonts, and discover how to give users more control over their content with text styles.

Speaker: Ned Holbrook

Unlisted on Apple Developer site

Transcript

This transcript has potential transcription errors. We are working on an improved version.

Thank you. Good morning. I'm Ned Holbrook and this is Session 223 Using Fonts of Text Kit. So let me give you an overview of what we're going to be talking about during this session. First we're going to talk about how to specify fonts in your app. We're going to be talking in particular about the new Dynamic Type technology in iOS 7. We're going to be talking about font descriptors.

We're going to be talking about the techniques for adding fonts to your application. And we're also going to be talking about a couple of topics that are going to be particularly relevant to developers of multilingual applications. Language tagging, a new mechanism available in both iOS X and iOS 7, and modifying fallbacks, also available on both platforms. Now, some of the material for specifying fonts is also going to be relevant for OS X as well. So if you manage to straggle in with -- in hopes of hearing something about OS X, you came to the right place.

First, I'd like to talk about Text Kit. I hope you've gone to some of the other sessions introducing you to this great new technology available in iOS 7. But since this Friday morning after the beer bash, let's have a quick review. Text Kit is the great new text framework based on Cocoa text and brand new to iOS 7.

It allows you to get amazing control and precision when it comes to typography in your app. And what's most interesting for this session is that both Text Kit and WebKit are built in Core Text which is our low level unit code layout engine available on both iOS and OS X.

Now, Core Text is still available to you if you've been making use of it in the past. And in particular, we think it's best for very specialized tasks. In fact, there's one task that it was built for and that was enabling the development of higher level Text Kit -- text frameworks like Text Kit and WebKit, maybe you've even have to build your own. But really when it comes down to it, we encourage you to use the highest level framework available that suits your needs. And particularly with iOS 7, we hope that will be Text Kit.

Now, no matter which framework you're making use of for advanced typography in your app. At the heart of it all, we're dealing with Unicode text layout. Now, this is represented by the equation String plus Font equals Glyphs. And when dealing with user content, there's really only one of those variables that you have control over and that's the font. The string is likely going to be the user's content. But we're going to talk about how you can choose that font correctly in order to get the best possible display of text in your app.

So let's find out how to do that. Well you've got a number of choices when it comes to choosing a font for use in your app. The most exciting one to me and I hope to you as well is dynamic type which is available for the first time in iOS 7.

There's also the system font that you are probably familiar with and you may still may need to make use of in iOS 7. We're going to be talking about UIFontDescriptor which is the class I use to identify fonts on the system. And as I mentioned, we're also going to talk about how to bring your own apps to your application or fonts, excuse me.

First, I'd like to show you an example of the new dynamic type technology in iOS 7. I hope you've seen some really wonderful examples of this in previous sessions, but since I'm going to be talking about some of the more technical aspects, so I thought I'd give you a quick refresher of this as well. Here we see the same Mailbox presented in mail on iOS 7 in three different content sizes.

Now, this is just three out of a total of seven that a user can choose from. But I wanted to point out here that on the left I have the smallest size, in the middle I have the middle size, and then on the right we're looking at the largest user selectable dynamic type size.

So, as we can see, mail is a very text heavy application. But it still has what we'd like to display as sort of hierarchy of type. So, you'll note that there're several different weights of type visible in this situation. But you'll note that regardless of the size of that type, there's a very clear relationship between the different pieces of text on screen.

And one of the great things about dynamic type is that it gives you the tools you need in order to present information using the same types of semantic distinctions in the text, and we'll be talking about exactly how to do that. Note also that as the type size changes, it's not all being fit into the same size box. Mail has a really great dynamic type citizen and it's actually reacting to the size of the user's preference and resizing the table view cells to match.

So even though by its very nature as the type gets larger, the information density decreases. Mail itself is reacting to that and responding to the user's choice. Note also that in addition to the seven sizes that are available, three of which I've shown here, there's also a switch that can add a bit of weight to those type styles, and that's available via accessibility settings.

So dynamic type is organized by what we consider to be usage. Each one of these is a text style as we like to call it. As you've seen in the previous session, there are, I believe, eight of these different usage categories for use with text styles. These are things like Body, Headline 1, Caption.

And every one of these different text styles is optimized for legibility. We'll be showing you an example of one of this in particular. But, again, remember that the user is responsible for picking the size of these text styles. So, for any given text style, you're going to see it in a number of different sizes. The metrics are going to change based on something that's out of your control.

That is the user is going to choose. And so, of course, we highly encourage that you adopt auto layout constraints for resizing your UI to adapt to the user's content. But even if you're not doing that, you may have some other techniques. You should be aware that these metrics are going to change.

And as I'm sure you've already seen Interface Builder with Xcode 5 has a great support for these text styles, so you can specify them right in line where you're designing your user interface. Now, let's take a look at one of these text styles in particular. On the slide, I've chosen one of the subhead text styles and what I have here is what's called the waterfall chart which is simply the same sample text set in all of the different user selectable sizes.

Now, you don't have to be a typographer to see that this text is clearly related, all these different sizes probably meaning the same thing. But again, not just sizes. We have a type system involved where this particular text style subhead is related visually to the other text styles and so one of these in conjunction with other text styles allows you to present a very, very rich information hierarchy. You'll also note that this particular text style -- all these different sizes have a very consistent -- what typographers call color. But let's zoom in and take a look at what I mean when I say that these are optimized for legibility.

So, we're going take a look at the smallest and the largest text styles sizes zoomed in to the same point size. And here I've taken the liberty of annotating the white space in this example to show you that besides having different weights of type in this particular example, we've also adjusted the letter spacing because a smaller text needs more room to breathe in order for us to ingest it with our brains and eyes to really dig into the context.

These sizes adjust both the letter spacing and also the line spacing which is hard to show on this particular example. But -- So, if you can consider that we have this grid of these different sizes, these different styles, there's really a huge amount of design effort that went into these typefaces and the great part is that they're all available to you.

So in order to make use of these text styles, this huge amount of design for this beautiful type, you'll probably been making use of UIFont preferredFontForTextStyle which is a class factory method on UIFont that takes a single argument which is one of those text style identifiers that you can find in UIFontDescriptor.

Besides the base text style categories, you can also make some changes to those by modifying them with symbolic traits. So the ones in particular that you're likely to find useful are Bold, Italic, and we also have special traits for adjusting the line spacing. So depending on the content being presented, you may be able to tighten the line spacing a bit if you're dealing with say a single label. Or for longer line lengths, you may find it necessary to actually loosen the line spacing to give a bit more of that white space that's needed for best legibility, and we'll be showing you an example of how to do that in code shortly.

Note also that all of this amazing technology is available in CSS as well. One of the earlier sessions, the Intro to Text Kit Session and you may have also heard in the WebKit session, there are properties corresponding to each one of these type styles -- text styles, they're prefixed with -apple-system, and so you can find the list of those elsewhere, but -- so if any part of your UI is still built using a WebView, that's all right. That's great. You can still access this great technology.

Now, text styles are part of a larger category of fonts that I like to think of as being sort of a metafont. So, you'll note that with text styles in particular, as you may have seen in that example, I know that the weight of the type was actually changing in response to the user preference.

And so naturally, you can assume that for a given text style, the actual font that's used to render that text to screen may not be the same in all situations. And so, we've also seen this on OS X where Mavericks brings a new system UIFont that's optimized for Retina Displays.

And so, as OS X developers, those of you in the audience who have done programming in OS X, you may be familiar with the various NSFont class factory methods for getting at what I would consider to be this system font, this semantic notions of what a font may be. You may have seen menu font of size, control font of size, these types of things. But, many of you may have also noticed that in the past whenever you used one of these, you typically got back the same thing every time, Lucida Grande.

And so you may have said, "well, you know, I mean this is great, but I know it's just going to end up being the same thing in the end. So I may as well just specify that in my code or in my zeb [phonetic] or whatever". But by doing so, you lose the ability to adapt to improvements that are made in the system font technologies.

You'll note that this is particularly so when it comes to text styles because it's not just that the font may be changing across releases, they're going to be changing dynamically and in the Intro to Text Kit Session, you saw how to adapt to that dynamically. But one thing that's shared with all of these fonts is that when you poke around, you may end up seeing font names that start with a period.

And, as we all know from our grand UNIX history, something that begins with a period is not meant to be seen. And so when you're dealing with these system fonts, if you find one of these, that's a sign to you, the developer, that not only are you not be presenting those names to the user directly, but it's also a note that there's magic involved.

And so really you should be dealing with these by identifying these system fonts using their semantic identifiers, this class factory methods, these text styles. And never -- would it be appropriate to drop down and grab a CD font and deal with that moving onwards. So, UIFont does have one of these class factory methods that you've seen before, systemFontOfSize, also Bold and Italic variants. But this is -- there's a clear distinction to be made now in iOS 7.

The system font is not meant to be used for user content, that's what text styles are for. And in addition, only if you recompiled your app for iOS 7 will that system font be adopting any of the new improvements made to the typography. So, keep this in mind when you're designing your app and your users will thank you.

So UIFontDescriptor or -- also a very similar technology on OS X, NSFont Descriptor, is the class that we use for describing fonts. It's a very, very lightweight mechanism. It doesn't involve spooling up any rendering system in order to have an actual font on hand. It's simply the mechanism we use for getting up that font.

It allows you to access and in some cases modify font properties. We'll be showing you that as well. UIFontDescriptor is the base technology for finding out what fonts are available to your app and it's also the mechanism by which you can specify your own fonts if you've licensed them for use in your user interface. So the way we use a descriptor is by noting that it looks a lot like a dictionary with key value pairs. In this case, those key value pairs are called font attributes.

They correspond to any number of particular properties that fonts have. It bears the names, the size, what typographic features might be enabled. And you'll note that using a descriptor, it's very easy to create one for a font that doesn't exist. For instance, I could use a descriptor to specify that I want a font that's in the Helvetica family and that its style is purp -- well, until type designers sort of embrace their synesthetic side when it comes to designing fonts, I doubt we're going to see purple being a commonly use style for a font. But, we're going to need a mechanism for finding out whether or not these descriptors correspond to actual fonts in the system, and then the mechanism we use for that is called matching.

So there's two types of descriptor matching when we want to take an abstract descriptor and turn into something more concrete, that is something that's based on the real font. And the first is explicit matching. You can invoke matchingFontDescriptors WithMandatoryKeys on a descriptor. And you'll get back an array of potentially many -- potentially no font descriptors that correspond to fonts that are actually available to your application at the time of that call. There're also various methods that perform this matching on your behalf and so this I like to consider implicit matching.

So, for instance, fontDescriptorWithSymbolicTraits which we'll have a code example of in just a moment, when you invoke this method, it will be using matchingFontDescriptors WithMandatoryKeys under the hood and so the results you get back will correspond to fonts that are actually available, and so in that sense, it's being done implicitly on your behalf.

In addition, you can create a font from a descriptor directly because, of course, when we want to materialize that descriptor into a font, we need to have something to use in that case. And so this method will also perform matching on your behalf but it also means that if you didn't explicitly make that match before hand, it might not be exactly what you expected due to having specified a font that doesn't exist.

So let's go ahead and make a match. On this code example, I'm creating a UIFrontDescriptor from a dictionary of font attributes. In this case, I'm specifying the family attribute with the value of Helvetica Neue, and I want to see what's available to me. So, as I mentioned, I invoked matchingFontDescriptors WithMandatoryKeys.

In this case, I'm going to pass nill. This is the most common situation, passing nill means to use all of the keys, all of the font attributes in the dictionary when considering what constitutes a match. But if you would like to only consider certain attributes in the font descriptor, you can use the mandatory keys to narrow that down. But, as I mentioned, in most cases, we'll just be passing nill to use all. If I run this on iOS 7, I'll get back an array with the number descriptors, 14, I believe, for various members of the Helvetica Neue family.

I mentioned also that we can use descriptors to modify text styles and other fonts as well. So in this case, I'd like to get at a Bold body text style and there's no category, no constant for specifying a Bold body text style, but I can apply the Bold symbolic trait to the standard body text style if I need some emphasis in my body text.

In this particular example, since I'm not starting from a UIFont, I don't need to spend everything up just to get at a font -- just to get another font, so I'm going to start by getting a UIFontDescriptor using preferredFontDescriptor WithTextStyle. I'm passing in the relevant constant, in this case, text style body.

And then we're going to modify it with the symbolic trait for Bold. In this case, I know that there's going to be Bold variant available but, again, if there's -- if I were using a different font and they weren't a Bold style available to me, then I would be left with the original descriptor, but that's OK because then I'll go ahead and create the relevant font, in this case, from that descriptor.

You'll note also that the size parameter that I'm passing in is zero. And that indicates that when using the descriptor, I'd like to not override the size that it itself specified. So, in this case, zero simply means don't change. And now I have my Bold text style for use in bodies.

Descriptors are also the preferred mechanism for serializing font data. So, of course, from a font descriptor, we can coerce to a font and for any given font, we can get a font descriptor that describes it. So this is relevant when we have a font that we'd like to serialize, we'll use this descriptor.

This is very easy since font descriptors can form to the UI -- to the NSCoding protocol, but you may have a mechanism for archiving and unarchiving objects that doesn't use NSCoding. In this case, you should be accessing the dictionary of font attributes on a descriptor. But note that because of all of the various possibilities when describing fonts, you should be using those attributes as an atomic entity. You shouldn't be trying to pick various attributes out of it and assume that that's going to be able to reconstitute a font on the other end, so just use all of these and serialize them as necessary. Descriptors can also be used to modify font instances.

Now, when I say modify, it don't mean that you're able to go in and change the font data on disk. But what you can do is change the behavior of a font when you make use of it in your app. Two examples in particular that we're going to see are how to activate typographic features and how to remove unwanted characters to limit the character coverage of a font. So, as I mentioned earlier, of course, String plus Font equals Glyphs, Unicode text layout.

Well one of the neat things about fonts is that they can often implement special features that modify that process in somehow and these features are called typographic features, and in this particular example, I have a font where normally when I layout text using this font, I get one appearance as you can see on the top here.

It says 11:15. And you'll note that even though this particular font, 12, you can't really see it, but this font is a proportional font that is it's not monospaced, different characters have different widths. You'll note that the digits in this font, they're all monospaced, the ones the same width as the five.

And this is a very common design that you'll see from fonts because it makes it easy to line up figures in columns, but I'm no accountant and I know that in this case, this particular string means that I'm trying to display a font -- a time to the user, let's say for time stamp in a table that I have data that I'd like to present. And so I've been told by my designer that this particular font has typographic features that allow me to apply a time appearance to it. And one of those is one that I can use in other cases as well and that's to make these digits proportional.

And so in this particular example, you can see very clearly how the ones now have a narrower width and since I'm dealing with time, this font, I've been told, has another great feature that I can use and that's an alternate set of glyphs. In this case, the alternate set includes a different colon that clearly looks like a time separator. Rather than being rectangular, you can see that it's circular and it's brought up off the baseline a bit.

So -- And this is what I'd like to use, how can I do this in code? Well, first I'd like to build up an array of feature settings. So feature settings are these -- are the identifiers, the handles onto these typographic features that can be implemented by a font and you can programatically query the fonts to find out what's available, but in this case, I've been told specifically which ones I need to use.

I'm using the Objective-C literal syntax for doing that, and so if we unpack this, you can see it's an array of two dictionaries and each of those dictionaries is specifying both the type and a selector as the key and the values are relevant to those particular features that I'm trying to enable on this font.

So, the first one you can see, it's very clearly described number spacing type which is kind of a grouping of features and then the proportional numbers is what I'm going to be enabling. And this other one, this character alternatives, you'll note this pesky little magic value, magic constant 1.

Well, so there are a number of predefined typographic features, names that we've given because we have seen them in so many fonts, but remember that typographic features are kind of like an API to a font. And so a font is free to define its own typographic features and that's exactly what this font has done.

It's defined a particular selector in that character alternatives type of 1. And so if that font came with a header, somehow we could, you know, give it a magic cons -- maybe we'll give it a name in your code so we know what's going on, but in this case, our designer has told us this is how to enable that particular change that you'd like to make in the appearance of the glyphs. So once we have that array of feature settings, what we're going to do is we're going to assume that we've started with the font already, that original font in the original appearance that you saw in the example.

We're going to get its descriptor. Now, we're going to create a new descriptor by modifying the original descriptor by adding attributes to it. In this case, there's just one attribute, it's the feature settings attribute and the value for that is going to be the array of feature settings that we defined above.

And then finally, we're going to say, UIFont, fontWithDescriptor. We're going to pass that descriptor that we just created with those feature settings. Again, we're going to pass zero for the size, meaning don't change it. And so now, the only difference between the original font and time font that we've made here is it's going to be the same font but it has these new features enabled.

And so the font gets to participate in that glyph selection process and during layout it will say, "oh, I know exactly what you want for those ones and that colon. I know you want this other glyphs instead." And these feature settings can be quite amazingly powerful. Not only can they change which glyphs are selected for certain characters, but they can also change the interaction between various glyphs, ligatures are a great example of this.

So another example, as I mentioned, is limiting the character coverage of the font. So, I've got this really great app. It's kind of technical and so I think Menlo is a great choice of a font for my -- presenting my user's content. And as I'm sure it happens to you a lot -- I -- so many at my documents include the Unicode snowman character, of course. You know, again, I think I've picked the right font for this particular very specialized app, but I don't know about you, but I think it's kind of a bit early in the morning for Menlo snowman, he's just too happy.

So really what I'd like to do is I want to use Menlo, but I don't want to ever see Menlo snowman. And so I want to create a font instance that acts as if it doesn't even exist and I'd like to just let the system pick a different font, follow back to different font whenever it sees a snowman. Anything will be better right now.

So I mentioned earlier in passing that UIFontDescriptor can be used to access font properties. And so in this example, I am going to be ultimately creating a new descriptor by modifying an existing one, but the value of the attribute that I'm going to be modifying. First, I want to get from my original descriptor. Let me show you how that works.

So, again, we're going to assume that we have our font, in this case, in the example I gave, it's going to be a font for Menlo. We're going to get this descriptor again, the original descriptor. Now, in order to compute what its character set is going to be, first we're going to get its original character set by invoking object for key on the original descriptor getting the character set.

We're going to mutate that by removing that one character, just that one snowman character. And so now we have a character set which is exactly identical to the original font's character set minus that one character. And then just as before, we're going to make a new descriptor by adding an attribute and the nice thing about this method is that it's defined as using the new values to override anything that is already in the font. So there is no conflict here.

It's going to know that this new character set attribute is going to be the one that I want and when I create a font with that descriptor -- now whenever I use that font in my app, it will use Menlo for all the text except that snowman character and in that case the font subsystem is going to pick up fallback fonts to use that to run to that character instead.

So there're also some great opportunities for you to bring your own fonts to your designs, your app design, and this goes not only for iOS but also for OS X Mavericks as well. So, if you're design includes something custom, this is how we'll make it work. So bringing your own font to the table is pretty easy. We've got lots of options. So when you're talking to your designers or the foundry from what you're going to license your font, they may ask you some of these questions. And so, these are the answers you're going to need to know.

We support both -- two type, an OpenType font containers, both individual fonts and as collections and in terms of the layout information in those fonts, we support both AAT and OpenType layout information. So, really, you shouldn't have any problem being able to get the font in a format that we can support. And then in order to make use of that, it's very simple, you simply place in your app bundle because that's how your resources are bundled.

And then the system can automatically make those available to your app on iOS by using the UIAppFonts Info.plist key to specify the location on those fonts and your bundle. There's also a corresponding Info.plist key with us, different name on OS X, but you may find, and I should say that once you've done this, it's -- it acts like any other font that was previously installed in the system. So you can say, "UIFont fontWithName and the name of that font that you've added and there will be.

But we found in some cases that for various reasons, this isn't what you want to use. And some cases, we found that foundries asked the developers like you, you know, not have their fonts just sitting on unencumbered in the app bundle to prevent casual snooping. And so in these cases, you might want to have [inaudible] the font data in some way and in fact, we have code example available online for how you might accomplish this on your app. But once you've done that, of course, the system can no longer automatically make that font available to you, and so you may need to add that font manually. There're two different types -- there're two different ways in which you can do that.

The first is by adding the font as what we call a registered font. Using one of these CT font manager APIs, you can specify the location of font data to be referenced by name after it's been added. These registered fonts, again, behave just as if they had been in your app bundle and activated automatically, so you just referenced them by name. There's another way in which you can add fonts however in which they're unregistered. In this case, the font's names can never be matched.

And you might say, "well, how was that even useful?" Well, it's really great actually because what you get back from these CT font manager APIs are new font descriptors. Now, of course, these are CT font descriptors, cortex font descriptors, but they are toll-free bridged with UIFontDescriptor on iOS.

So, just a little bit of casting is all you're going to need to make this work. Once you have one of these descriptors, of course, we've seen several times now how you can create a font from a descriptor, and that's exactly what you can do with these. So even though you can't say font with name, your fonts name and get back the fonts. In this case, you can create a font directly from a font descriptor.

This could also be helpful for instance if you license a particular version of a font that already exists on the system. And so, if you for some reason has special layout considerations and need to use your own copy of one of our fonts, this is a great way to make that happen.

Now, for making it this far in the conference, in the session, we'd like to show you another little surprise here. So in iOS 7 -- well, iOS in general, we've long had the problem where on OS X, we have a bunch of really amazing beautiful fonts. But until we can get that shrink ray working, it's really hard to squeeze a terabyte of storage into a little phone that goes in your pocket and so many of these fonts we've had to leave out of iOS because there's just not enough room.

But there are cases when you might know that you just need to use a particular font. And so, what we've done for iOS 7 is we've made a huge number of fonts available to you. We've licensed and hosted these so that you can make use of them. These include literally hundreds of fonts, all of the fonts installed in OS X as well as additional fonts for particular support of international scripts. And the way -- thank you [applause].

So the way you take advantage of this is by using a very long API CTFontDescriptor CreateMatchingFont DescriptorsWithProgressHandler. And really, what this is, is it's a very special type of descriptor matching. So we've talked about this already and before we saw how simple it was to match on a descriptor and get the results. Well, with downloadable fonts of course, were at the mercy of the network.

And so essentially what this is API let's you do is it lets you perform that descriptor matching asynchronously. And so the progress handler is a block that you pass in that gets called to handle the various states during the download. And so what this means is that in order to make effective use of these downloadable fonts, your app will probably have the design some UI to allow the user to recover from various failure states.

But with that in mind, it's very simple to query fonts are available via this download mechanism by matching on the downloadable attribute. And we'll also be publishing a list of those fonts online as well. So, to make use of one these fonts, I -- your app can simply download it and then the user's content is available in that particular app.

Note also that with iOS 7, fonts can be installed by managed profiles. This could be great if you're in an enterprise distribution scenario and you have multiple apps that you want to conform to a house style. And so, those fonts can be included in the profiles and activated in that way.

Note however that this is the first time in which fonts on iOS can change while your app is running. And so, if you'd like to react to fonts becoming available via a profile, you'll want to subscribe to the registered fonts changed notification so that you can react when that happens.

So, as I've been talking, we've been focusing on Unicode text layout. And Unicode is really an amazing specification because it allows us to communicate using nearly any of the world's languages on a computer which is no small task. But one of the sort of problems with Unicode is for -- in certain situations, the characters themselves -- we know that they can take on different appearances via the font but there're also situations in which the appropriate appearance of that character is dictated by the language. That is its information that the user has that isn't reflected in the text, can't be. And so, the system by default does the very best job it can in resolving these scenarios.

Typically, it does solve by looking at the user's preferred language. So, if the user is using her phone in Japanese, in the text appearing in Japanese, the system will select appropriate Japanese behaviors for text. But there are cases in which you or your content may know more about what the appropriate language is and the mechanism for doing that is by language tagging.

So, there's -- on Mavericks and iOS 7, there's a new string attribute that allows you to specify the language as an ISO language tag. And the presence of this attribute indicates that, that particular language should be used to override the default system behavior in various ways. You're going to be looking at glyph substitution, line breaking, and font fallbacks.

So the first example is one that's kind of -- may not be a particularly useful because this relies on a particular font. But this is another example of how fonts can participate in the layout process. In this case, I'm going to be displaying a particular string with two very specific Unicode characters and I'm going to be showing you the appearance of that string when laid out using one of two different languages that I've tagged the string with. In the case where I specified English as the language, we'll get, for these characters, their default appearance which you can see kind of looks like a little hook or tail on the bottom of each of these, the S and the T.

But what's interesting about these characters is that when use for Romanian text, they actually take on a different appearance. In this font, Verdana, actually implements that appearance. And so if I specified that language as being Romanian, you'll see that rather than having a little hook or tail on each of those glyphs, we have what looks more like a comma or a stroke. And this is great as a feature because it allows fonts to be more responsive to the user's languages.

Another way in which language tagging can affect the behavior of text is in line breaking. So here we have an example where I have a Japanese string. You'll note that I've asked to lay this out in the space up to that dotted red line on the right there. And you'll note that when I'm doing so in the context of an English user, the line break position is actually different than for Japanese.

That's because in the absence of any information about Japanese -- the Japanese text, the system uses the default Unicode character properties which isn't really appropriate for Japanese text. Now, again, as I mentioned earlier, if the user is running with Japanese as their primary language, they'll get the correct behavior by defaults but you may be writing an app in which you know that text should always have -- should always be treated as Japanese text.

Maybe you're writing a dictionary app or maybe the content is being specified using HTML and tagged as Japanese. And so in these cases, the system can adapt accordingly. And one of the most common examples when dealing with this quirk of Unicode is for languages like Chinese and Japanese where many of the characters actually overlap in Unicode. They can have the same character but different appearances.

In this particular example, we have a very obvious difference of appearance when we're dealing with either Japanese or Chinese as the language for this particular character. So in this case, what the system actually does is -- note that I haven't specified a font on my attributed string and so this is going to immediately trigger fallback which is the process of finding a font that can actually render that character.

And by specifying the language attribute, I've told the system exactly what it needs to know to make the right choice, not just a good choice but the right choice. And in this case, it's going to select one font for Japanese and a different font completely for Chinese. So beside the appearance of just this one character in a real world situation, the user would notice that there're other stylistic differences or even other glyph differences between those two fonts and so this can be done automatically.

So on that note, I'd like to talk about one other technique for changing the behavior of fallbacks and that's by making use of a custom cascade list. We've seen how an app can tag a string with the appropriate language to get language specific behavior but there are other cases beyond just that when we might want to make a change to the fallback behavior.

The cascade list attribute is a font descriptor attribute that you can add that allows you to specify an array of font descriptors that will be used before the default list when performing fallbacks. So, what does that mean? Well -- so remember, I mentioned that the system has a default behavior that works as best it can.

But in this case, you have the flexibility and the power to insert something that's going to be checked before that list. So let's take a look an example to try to clarify this. So let's say I'm marking on an Arabic dictionary app and I have a -- I've specified a really great font in my design for the English headwords but the behavior I'm seeing is that when the text system encounters the Arabic characters in that string, they're falling back -- the fallback font that's selected to render those characters is Geeza Pro.

Now, some people will call Geeza Pro time tested. Others would call it long in the tooth. But more importantly, I think what's important to note here is that Arabic is a writing system with a very rich calligraphic history and so there are a number of different styles in which I could expect this text to appear and Geeza Pro is just obviously one style.

So what I've done is I've licensed a really beautiful Arabic font for use in my dictionary and I'd like the system to manage the transition between those fonts automatically. And so what I'd like instead is when I specified my original font from my headwords, I'd like to let the system take care of the fallback by overriding the default behavior, not going to Geeza Pro and selecting my font instead.

So in order to do that, I'm going to want to specify my own cascade list. So I've got a font descriptor. We'll, assuming that I've constructed font descriptor for my licensed Arabic font and then I'm going to build a cascade list which is pretty simple using Objective-C literal syntax, I'm just going to have an array with this single object and that's going to be that descriptor. I'll assume that I have my font for my English text.

Again, like we've seen before, I'm going to get the original descriptor and I'm going to create a new descriptor by adding my cascade list attribute to that descriptor. Now, whenever I make use of the font that I can make from that descriptor, what will happen is -- I know that this font doesn't support Arabic characters.

And so whenever the string contains those characters, the system is going to need to consult the fallback to find an appropriate font to render that. And so, this cascade list -- since I know this covers Arabic characters, it'll be used rather than the default fallback which is Geeza Pro.

So, you may note also that this particular example could be quite powerful when combined with a previous example of modifying the character set. And so they're depending on the needs of your app. You may even be able to combine the various techniques that I've shown you for a very precise control of the fallback behavior.

For more information, there are various resources available to you. There are a couple of sessions that are available on instant replay to you and I encourage you to review those because there're some really fascinating concepts in there as well as several of the design sessions on designing your user interface for iOS 7 because that will give you I think some really great ideas for adapting text style in your apps. And I, as a user, I'm really excited to see what you guys can come up with.

In summary, I just like to drive home a couple of points one more time. The first is to -- in order to adapt dynamic type in your iOS 7 app, you'll do so using text styles. Remember that this is -- this requires a bit of flexibility on your part in order to adapt appropriately to the user's desired content size. So please investigate using auto layout but keep in mind that those font metrics are going to change based on user preference. For developers in multilingual situations, language tagging is a great feature that allows you to specify language sensitive behavior.

And what's really great about it is that -- in those examples I showed you, that attribute will flow right up to your Text Kit and you'll get perfect behavior. For various specific needs involving fallbacks, you can influence the systems fallback behavior by adding a cascade descriptor. Remember also that profiles can install fonts and so this is a new tool available to you as well and those fonts are available systemwide. So with that, I'd like to say thank you very much for coming to hear about fonts and Text Kit and a little bit of OS X. Thank you very much. Enjoy the rest of the conference.

[ Applause ]