[ Cheers ]
[ Applause ]
Good afternoon everybody!
Welcome to WWDC2017.
My name is David Duncan.
I'll be joined by Raj Ramamurphy [phonetic] and Kyle Sluder [phonetic].
And we're here to talk to you about updating your app for iOS 11.
So first a little agenda for what we're going to talk about today.
The first thing that I'm going to be discussing with you is adopting new functionality in UI kits bars; UI navigation bar, UI tab bar, UI toolbar, and UI search bar.
And we're going to talk to you about how these can update your app to the new looks that we've introduced throughout iOS 11.
Next Kyle will come up and talk to you a bit about managing margins and insets, changes that we've made to UI scroll view and table view will come after that, and we're going to use all that to show you how you can make your app better.
So let's start by taking a look at the files app.
So if you've gotten the chance to install the beta and take a look at the files app, you'll see some changes that it's taking advantage of from UI kit.
You can see that giant, large title view up there showing the browse feature.
You've got a search bar right below it that has a bit of a different appearance from any search bar you've probably seen before.
Now the tab bar actually has some changes, but you won't see them here so let's go ahead and rotate this to landscape.
We've got this brand new appearance for the tab bar, both in landscape and on iPad, where we show the icon and the text side by side.
And in particular on iPhones the icon is smaller and the tab bar is smaller to give a bit more room vertically.
We're going to discuss how you can customize the icons for landscape and tab bar as well.
Now things getting smaller can sometimes be a problem for users that are hard of vision or otherwise need a little assistance to see things clearer.
We've got you covered there too.
If you turn on larger text then when you long press on one of these items this is in tab bar, tool bar, and navigation bar we'll put up this HUD that shows you clearly what the text is and what the icon is.
And now I'm going to explain how both of these features can be adopted in your app and they're really, really easy.
So there's this class called UI Bar Item that you probably never thought much about because it's actually the super class of two important bar item classes in UI kit; UI tab bar item and UI bar button item.
And so to customize the image in landscape on that tab bar all you have to do is set this property, the landscape image phone property, on any UI tab bar items that you're placing in your tab bars.
And of course we'll have support for this in storyboards and everywhere else, but that's how you would customize that.
And there are also some inset properties in case you need those.
For that HUD image we've got another related property called the Large Content Size Image.
Now you can set this, put a big image in there, it'll appear in the HUD, but if you're using PDF assets in your asset catalogue it's even easier.
All you have to do is set that preserve PDF data and we'll automatically pick up the PDF data, resize it larger, and display it in that HUD without you having to do anything to your assets.
So if you wanted to learn more about accessibility features such as the HUD and how you can pick that up, there's the What's New in Accessibility session happening this Wednesday.
I recommend you go there to learn all about what's new in accessibility in iOS 11.
And so let's talk next about navigation bar.
How do we get those large titles that appeared in the files app and other apps across the system?
So first there's a new property on UI navigation bar, prefers large titles.
If you set this to "true" on any given navigation bar then you'll start seeing large titles all across the system all across your application.
Now you might be wondering; what do these other three words that I've got here on this slide maybe they're a little hard to see, but automatic, always, and never what does that have to do with?
Well, there's a second property to control when these appear; the large title display mode.
This is what easily allows you to determine for each view control you push onto a nav controller or to a navigation bar stack when the large title appears.
And let me show you how that works.
So we turned on large titles on this navigation bar and we put an item on there.
It defaults to automatic and automatic means whatever the current state is, whoever asked last for that bar to appear, keep it.
Since nothing else is on the stack and we turned on large titles, we have a large title.
But let's go ahead and push a navigation item that we don't want to display that large title on and we just set the large title display mode to "never" and the large title goes away.
Now again we'll push an "automatic," preserve whatever we have now, and so we don't get a large title, and then we'll push "always," and now the large title is back.
And again, we can push an "automatic" and we're all there.
Simple. So there are two more things we want to talk about on navigation item and the first is how to integrate the search controller and the new search bar look with your navigation bars.
There's a single property again, navigation item search controller.
You assign your search controller to the navigation item and you're done.
The search bar is placed correctly and it behaves just as it does in a lot of our apps.
Now if you've actually gotten a chance to play with "files" or "mail" or some of the others you'll notice that sometimes that search bar stays pegged when you scroll, sometimes it does not.
In particular in "files" it stays pegged and that's controlled by this "hide search bar when scrolling" property.
It defaults to "true."
So, for example in "mail" it scrolls away, but in "files" they've turned it off.
And so it stays pegged.
You can always reach the search bar and it looks great.
So how does all this work?
A little bit of behind the scenes on some of these things.
And the first thing you should know is that a lot of these interactions are actually mediated by UI navigation controller.
So if you're taking the navigation bar and assembling kind of the entire push and pop experience yourself, and not many people do, but if you are you're not going to get some of these features.
In particular you're not going to get the search controller integration.
You're not going to get refresh controls hoisting and you're not going to get rubber bending.
Rubber bending is when you start pulling down, that large title grows larger, and responds to that scroller.
So that's navigation bar, navigation controller, and those new large title features.
But while we're here making all of these changes we figured let's actually make some other changes to help your lives be easier as well.
And so now in iOS 11, UI toolbar and UI navigation bar both have intricate and express support for auto layout.
[ Applause ]
So what this means is that your custom bar button items, your custom title of use, can now use layout to express their size to us and get the proper layout that you would otherwise expect.
Now there are a few things to keep in mind.
One of them is you kind of want to keep your constraints inside of that view.
So if you give us a custom title view you want to make sure that any constraints there only reference that title view and any of its sub-views.
And this one is kind of big, but it's kind of worth bringing out, is that when you use auto layout we also assume you know what you're doing [laughter] and the reason why I bring this up is because otherwise you end up in this case where you have to you get zero sized views.
So how do you avoid these zero sized views?
Well, UI navigation bar and UI toolbar provide positioning information.
Zero sized views end up becoming because you have some ambiguous constraint layout.
And so the position is taken care of for you.
You won't get your views shoved up in an upper left corner somewhere, but you still have to provide sizing for us.
And there are three ways you can do that.
You could add constraints for width and height; perfectly legal, perfectly legitimate.
Do that. You can put whatever else you want in there and you're golden.
You could also implement intrinsic content size.
That'll also give us as much information as we need.
You go along with the content compression hugging and compression resistance and you're set.
But finally, the most easy way, for most people, is to actually make sure that all of your sub-views are properly connected and set up with auto layout.
And what that means is let's say you have a custom title view and you have a label and a button in there, if you want to make sure that you get the proper horizontal width of that title view you just need to make sure that there are constraints set up between those labels and buttons such that the leading and trailing edge, or the width, of that title view is defined in terms of those two views.
And so that's how you can use auto layout to add precise control to the size of your custom title views and bar button items.
Now, to demonstrate all the things we've talked about today we bring up Raj Ramamurphy to give you a demo.
[ Applause ]
So as David just explained, we have a bunch of great new API in iOS 11 for these new, large navigation bars.
I'm going to walk you through updating an app for iOS 11.
So here's a sample app we're going to be working with today.
It's a pretty simple app called "Trail Diary."
It's just a diary of some trails I visited.
So here we are in the main view controller, which I called the "memory view controller."
Now, if I tap on one of these cells you'll notice I get a detail view controller.
This contains a photo, a description, and some information about this.
There's also a way to add comments, and we're going to get into that a little bit later, but for now let's start updating this app for iOS 11.
One of the first things I'd like to do is introduce support in this application for those beautiful, new large titles.
So let's go ahead and do that.
We'll go over to the navigation or sorry to the memory view controller here and we're going to get the navigation controller.
Get the navigation bar and set the "prefers large titles" property on the navigation bar.
Now, when we set this property we get large titles everywhere.
And if I recompile and rerun the application, head back over to it, and bring up the memory view controller you'll notice we have this beautiful, large title, and since we already have a refresh control that gets hoisted into the navigation bar and we get the rubber banding experience everything's looking great.
Now, "prefers large titles" will turn large titles on everywhere.
So if I tap back into the detail view controller you'll see we get a really nice transition and we have the detail view controller showing a large title as well.
Now this is great, but sometimes the large title isn't what you want everywhere.
And so for that, as David explained, we have the navigation item property, "large title display mode."
So in this view I'd like to show the standard inline title.
So let's update this view controller to show that.
If I go over to the detail view controller and set its navigation items' large title display mode to "never," as David showed you before with the stack, if we recompile and rerun the application, we'll start out with the large title, but if I push view controller now we have this standard inline title and you get a great transition between them and everything's looking really great.
So that's how to use the navigation item properties for showing the large title, but I'd also like to add search to this application.
So I've already gone ahead and configured a search controller instance and I just need to show the search bar in the application.
As you may have seen, we're showing search bars in the navigation in iOS 11.
So let's add that appearance.
If I go over to the memory view controller again and set the navigation item's search controller property to our instance in this case it's just called "search controller."
Recompile and rerun the application.
You'll notice when the application comes up into the memory view controller, we still have the large title, but now if we pull down we get this beautiful new search appearance.
So this app is looking really great.
So that's just how to update some of your bars for the new appearance in iOS 11.
Now I'd like to bring Kyle Sluder up who's going to talk to you about margins, insets, and scroll views.
[ Applause ]
Thank you Raj.
So in iOS 11 we've made a number of improvements to give you more information and better control over how your views lay out their user interfaces.
And let's start by talking about layout margins.
Layout margins are a portion of the interior of your views that UI kit gives you as a guide to layout your content and give a little breathing room between it and the surrounding user interface elements.
And we give this information to you in two ways.
The first is a UI layout guide object, which you can use with auto layout to position your content.
The second is a set of edge insets.
And you can read these from your view and write to them to customize your layout margins.
In iOS 11 we're adding a new property; directional layout margins.
And this allows you to express the layout margins in your views, not just in left and right terms, but in leading and trailing.
And these two properties are in sync with each other.
The left property is in sync with the leading, when you're writing in an LTR or left to right language.
And the right property and the trailing property are in sync.
So I can do something like write a value to the trailing property of this view, which will cause its layout to adjust, and then when I'm running in a right to left language that trailing space will be put on the left side of the view and my layout code can then read it from the left property of the layout margin.
[ Applause ]
You may also be familiar with a behavior that has existed since we introduced layout margins where adding a view to a view controller would fix its layout margins to UI kit defined values.
Well starting in iOS 11 these are no longer fixed values.
They're actually minimums.
And we communicate the size of these values to you with this new property, system minimum layout margins.
And you can change your view's layout margins to any greater value, no changes needed.
[ Applause ]
But we went one step further and we added another new property on view controller; view respects system minimum layout margins.
If you set this to "false" you can actually change your layout margins to whatever value you want, including zero, and you can have full width content in any view including those that are managed by a view controller.
Since iOS 7 we've had these translucent bars throughout the operating system and we've encouraged you to draw your content through those bars, as you can see happening here in the photos app.
The way that you do this is using the edges for extended layout property on UI view controller.
And what this does is it causes container view controllers to size your views underneath the bars.
By default it applies to all edges and we communicate to you the size of the overhanging bars via these two properties; top layout guide and bottom layout guide.
Starting in iOS 11 we're deprecating these properties and replacing them with a new, more powerful construct that we call the "safe area."
The safe area is a way of describing the portion of your view that isn't occluded by any content.
It's available to you as a set of insets or as a UI layout guide object.
And on TV it incorporates a very useful bit of information called the "over scan compensation insets."
So any view on the screen can layout its content and make sure that it isn't overlapped by the physical bezel of the television.
Now if you have a custom container view controller, you might be adding your own bars and you can increase the size of the excuse me you can increase the size of the safe area insets via this new property; additional safe area insets.
And if any of your ancestor view controllers change their size of their safe area insets you will get a call back in two different ways.
Every view can get safe area insets to change and view controllers can get view safe area insets to change.
[applause] Thank you.
[ Applause ]
So one really common view that's used with UI view controller is UI scroll view.
And in this little sample here I have some text that's inside of the UI scroll view and contained within a navigation controller.
Now traditionally navigation controllers would impart a content inset to the scroll views of their topmost view controller.
We're making a really big change here in iOS 11 and we're no longer populating the content inset property through scroll views.
Instead we've added a new property, adjusted content inset, that includes the sum of the content inset and any overlap from container view controllers.
This means you can use the content inset property for whatever purposes are appropriate for your application, such as this additional information about this text here, and we won't change it.
And you don't have to worry about saving and restoring any UI kit provided values and having content underlapping navigation bars or the status bar.
[ Applause ]
You may be familiar with our auto layout support in UI scroll view that lets you dictate how big the scrollable region of your scroll view is by constraining sub-views to the scroll view itself.
And we've added a couple of UI layout guide objects that make your layout more clear and more expressive and more powerful.
The first is a UI layout guide object called the frame layout guide.
And this layout guide corresponds to the position and size of your scroll view in screen space, which means you can do things like constrain the sub-view, like this page indicator, and it will stay fixed on screen as the user scrolls.
The second layout guide object we've added is the content layout guide.
And you can contain your sub-views in order to influence the scrollable size of your scroll view or have things move as the user scrolls.
One really common sub class of UI scroll view is UI table view and we've made a number of changes here too, the biggest of which is that table views use self-sizing by default on iOS 11, not on tvOS.
This means that your headers, your footers, and your cells are using estimated sizes.
We've done this by changing the default value of the estimated size properties on UI table view to this constant, automatic dimension.
This means that you need to ensure that your cells all have sufficient internal constraints to tell UI table view how big they should be or you need to implement the delegate methods that tell us how big your rows are.
You should also implement those delicate methods for you headers and your footers.
Now maybe you want to link your application against the iOS 11 SDK, but you're not ready to adopt this new behavior.
You can opt out of it by setting the estimated height properties on your table views to zero.
That will turn off estimated sizes, which will also disable self-sizing.
Now you may be familiar with another concept we introduced a while back called the readable content guide.
And this is a portion of your views that if you lay out your content within, will be comfortable to read even on a large device like an iPad in landscape.
Now by default table views have a separator inset that is within the readable content area and this influences the position of the separators and of the labels in the table use content view itself.
And if you change the separator insets' values you would see that the separator inset moves relative to its readable content guide position.
Starting in iOS 11 we're changing this and the separator insets will always be relative to the edges of the cells themselves, which are the full width of the table view, which means you can set these values to zero and have full width, full bleed content even on an iPad running in landscape.
And this is a table view on an iPhone and if I change the separator inset here you can see that it is also defined relative to the edges of the cell to the edge of the table view.
We've added a new property to UI table view, separator inset reference, that you can use to tell us that you actually just want to adjust the separator inset from its default automatic position.
And this works on iPad too.
A couple of things to keep in mind about the way the table views interact with the safe area; those automatic separator insets are relative to the safe area insets.
So by default the entire content of your table view avoids the safe area insets from its ancestor view controllers.
UI table view cell and UI table view header/footer view, which might be one of the longer names in the kit, they both have a content view property.
That's where you should be adding your sub-views.
Both of these classes make sure that that content view also avoids the safe area insets.
So you should be using UI table view header/footer view for all of the headers and footers in your table views; table headers and footers and section headers and footers.
We've also brought over the really rich swipe action functionality from the mail application to your applications.
So on iOS 11 your applications will get the new swipe action look and feel by default, and if you link against iOS 11, you can get full swipe to delete behavior, just like you're used to from the mail app.
And if you go ahead [applause] some people are very excited about this I know.
[applause] And if you go ahead and adopt a few new APIs you can get some really cool features, like images in your swipe actions, or swipe actions from both the leading and the trailing edges, or a completion handler that lets you cancel the swipe action.
And to show us how to adopt all these features in our application, Raj is going to come up and give us another demo.
[ Applause ]
So we're going to switch over to the demo machine again and as you can see we've got these big beautiful bars in this new application.
It's looking really great.
But I want to show you the comments view controller.
Now if I push into the comments view controller here, you'll notice we have some really interesting comments and we've got all the comments here in a comment bar at the bottom.
Now our users have been asking us for one thing and that's time stamps.
And so I went and spoke to our designer and got this really cool design for this awesome new scroll bar.
This scroll bar also indicates, not only where you are in the comments view, but also the time stamp where it's pointing.
So let's go ahead and implement that.
I'll switch over to the comments view controller and create our scroll bar using a method I wrote earlier.
And when I recompile and rerun the application, scroll down, tap on one of these cells, and into the comments view controller you'll see there it is.
So it's looking pretty cool.
It shows you where you are in this comments view controller and the time stamp of the cell that it's pointing at.
But, as you might notice, there are a few issues here.
The first issue is that this indicator actually overlaps with the table view cell a little bit and so it makes things maybe a little bit hard to read.
The second thing is that this indicator overlaps with this input field here at the bottom.
So let's use some new APIs in iOS 11 to help solve these problems.
We're going to use the additional safe area insets property on UI view controller to help solve this.
So I'll go ahead and unwrap our two views and I'll set our additional safe area insets to a UA edge insets.
So on the top we don't have anything additional to add.
On the left that's the same story.
On the bottom we want to make it the comment bar's size.
So we'll get the height of the comment bar and on the right we have a property that I've written earlier on the side indicator that gives its preferred width.
So now we've set up our additional safe area insets.
If I recompile and rerun the application, head into the detail view and again into the comments view controller, you'll notice things are starting to look pretty good.
We've got our content inset from the right edge and the scroll indicator's also inset from the bottom edge, but you'll notice here, down at the bottom, that this comment field actually is inset a little bit from the right edge of the screen.
So the reason for that is the comment field's text field is constrained to its super views layout margins.
Now in iOS 11 your layout margins are actually inset from the safe area and because we added additional safe area insets on the right of this view our layout margins get inset accordingly.
Now most of the time this is going to be exactly what you want, but we do have a property on UI view, "insets layout margins from safe area," which lets you control this property.
So for this use case let's go ahead and set that to "false."
When I go ahead and do that, recompile and rerun the application, go back into the detail view controller and finally into the comments view controller, you'll see things are starting to look really good.
We've got our content at the right spot.
We've got our beautiful new scroll indicator.
Everything is inset and the comment field is a full width.
Awesome! The next thing I'd like to show you is adding swipe actions to this application.
So I've decided that I'd like to add the ability to favorite and maybe delete some of these things.
So let's go to the memory view controller and add support for the new swipe actions in iOS 11.
So it looks like a lot, but I'll walk you through it.
All I've done is implemented two new methods; leading swipe actions configuration for road indexpath and trailing swipe actions configurations for road indexpath.
So let's walk through the leading one.
All I do is I create a UI contextual action here, with a style of "normal," a title of "favorite," and a block based handler.
I update our favorites state, using a method I wrote earlier, and then I call the completion handler with the parameter of "true."
Just so everything's looking right, I'll also set it to "unfavorite," based on whether that item's already favorited.
And then I'll set the image to this beautiful star that I had made earlier and the background color to this awesome looking orange.
And then all I need to do is create a UI swipe actions configuration using that UI contextual action and return it.
The story's pretty much the same for the trailing actions; I just use the style of disruptive.
So when I recompile and rerun this time, go back over, and swipe, you'll notice we get this option swipe actions and you can even have a swipe action on the leading edge, as you see here, which you were never able to do before.
For full furthermore, you get full swipe to delete support out of the box.
So all I need to do is swipe all the way across and it just works.
[ Applause ]
So that's a look at some of the new APIs for margins, insets, scroll views, and bars in this demo app.
It's looking really great and definitely ready for iOS 11.
Now Kyle's going to come back up to tell you about some related sessions.
[ Applause ]
Thank you again Raj.
So just to recap what we've learned today; we've learned how to adopt large navigation titles and the new integrated search experience into our applications for iOS 11.
We've also learned about some new improvements to layout margins that give us complete control over our views and the way they layout, as well as a new concept called the safe area, which tells us about overlapping contents and things like over scan compensation insets on Apple TV.
We've learned about some new enhancements to UI scroll view that give us better control over our content inset and some new features in UI table view and how it interacts with concepts like the safe area.
If you have more questions be sure to visit the site for this session.
Have a great WWDC.
[ Applause ]