More Videos

  • Build for iPad

    Learn how to improve iPad apps to leverage the increased screen size and additional features of iPadOS, and help people accomplish more with their devices. Discover how you can build detailed multi-column layouts and integrate lists into your app with little adjustment to your existing code. We'll also explore reducing modality within your views to make it easier to navigate your interface with fewer taps and touches.

    To get the most out of this session, you should have a general understanding of iPad app layouts and UIKit. For more information, watch “Making Apps Adaptive, Part 1.” And while not necessary, familiarity with UICollectionView may also be helpful. Watch “Advances in Collection View Layout” for an overview.

    Want to learn more about list creation for your apps? Watch “Lists in UICollectionView”.

    Resources

    Related Videos

    WWDC20

    WWDC19

  • Hello and welcome to WWDC.

    Hello, I'm Kurt. Welcome to WWDC.I'm here to talk about "Build for iPad."We're here to talk about making your app work great on the iPadusing new features and a new look in iOS 14.

    We've redesigned our apps, like Mail, Notes and Hometo take advantage of the power of the iPad.I'm going to point out some specific UI featuresthat you can implement too.Mail has a new look with multiple columns.You can easily see just your e-mail or all of your mailboxes.With just a few simple gestures, you can hide or show exactly what you want.

    The sidebar list design is simple and clear.When I tap the edit button, now there are a lot more controls available.It's easy to build a simple list and then add accessories to it.In Notes, we've made it easier to get work done without all of the extra taps.For example, I brought up the color picker to choose a color for my marker.When I draw in the document,it automatically dismisses the color pickerwithout needing a tap.Here's another example.The new design of Home on iPad has a sidebar with a list.When you use Catalyst to bring your app to the Mac,all of these features work there too, but they also use the new Mac design.We'll tell you how you can do the same with your appusing new functionality in UIKit.Multi-column split view is now available. We'll give you an overview.

    We'll talk about how to implement lists in those columnsand how to get the right look.We'll talk about reducing modality in your UI,and we'll give a case study how the Shortcut app did all those things.So, let's begin.The heart of a multi-column app is UISplitViewController.It's a container view controllerthat provides the structure around the contentthat you provide in your view controllers.In iOS 14, there's new API that makes it easy to set up and work with.

    Use this new initializer that specifies a style.Using this initializer enables new behavior and more new API.

    The style says up front how many columns you want.Use the double-column style for two columns.We call these primary and secondary.

    Then you specify which view controller goes in which columnby calling setViewController for a specific column.

    For example, Home can provide one view controller for the primary columnand another view controller for the secondary column.

    Three columns is just as easy. Use the triple-column style.What goes between primary and secondary?We call the new column in the middle "supplementary."Again, call setViewController to provide the view controllerfor the supplementary column.For instance, here's how Mail sets up their supplementary column.That's all you have to do to get double- and triple-column layouts.We've said this before, but to emphasize,we recommend you have one app for iPad and iPhone.

    If your app is structured into columns,use UISplitViewController as your window's root view controller.

    It handles the columns for you by showing the right view controllersin the right places at the right time.

    What happens is based on size classes.

    There are cases when there is a lot of horizontal space,like iPad full screen and large iPhones in landscape.We call this the regular width size class.

    Because there is so much room,UISplitViewController can show multiple columns side by side.

    In other cases, there's not so much horizontal space,like iPad apps in slide over and iPhones in portrait.We call that the compact width size class.

    There's clearly no room to show multiple columns,so what do we do?You can choose to specify a separate view controllerthat's used when the width is compact,and it can use a different navigation schemethat's tailored for the space available.You give us another view controller for that columnby calling setViewControllerForCompact.

    That's all. We do the rest.For example, here's Shortcuts.They use a tab bar controllerto implement a different method of navigationthat works in that smaller area.To sum up, don't think of it as designing an iPad app and an iPhone app.Instead, you're designing two experiences--regular width, which has multiple columns, and compact width, which doesn't.Let's go back to talking about multiple columns.There are a lot of ways we can lay out those columnsdepending on how much space we have and how big they are.We call these display modes.

    We can show the secondary column only.That's when you're focusing on your contentand you've hidden all of the other columns.You can show a single column beside your secondaryor over, above the secondary.

    If there are three columns, there are even more choices.You can have two columns beside the secondary,or over it, or they can even displace it, pushing it aside.

    To move between these display modes,SplitViewController automatically creates appropriate buttonsand makes them appear in the right places.For example, here we're showing and hiding the columns in Notesby pressing buttons.You can also swipe from the edge to show more columnsand tap to hide all of the columns.

    The buttons and gestures are enabled by the property presentsWithGesture.By default, it's "true," but set it to "false"and those buttons and gestures go away.The property showsSecondaryOnlyButton enables an additional buttonwhich hides all but the secondary column.You just saw that in Notes.The preferredSplitBehavior property can be setto determine what display modes the buttons and gestures will use.For example, if you prefer that the columns are side by side in your app,use the tile behavior.Pressing the button will move through these display modes.The displace behavior is similar, but when three columns are shown,we push the secondary column partially off-screen.

    The overlay behavior, of course, uses the overlay display modes.

    At any time, you can request that a column be hidden or shown.Just say which column you want to change.UISplitViewController will automatically do a smooth transitionto fulfill your request.

    Finally, if you know your app always wants the same layout,specify that with preferredDisplayMode.For instance, an app like Remindersthat always wants to have two columns side by side,would set preferredDisplayMode to oneBesideSecondary.I said the buttons get added automatically. How does that work?Because each column now has a navigation controllerthat's automatically created for you.And each navigation controller has a navigation bar at the topand an optional toolbar at the bottom.That means that UIKit can put buttons in those bars,and so can you using the standard methods.

    There are a lot more details.We recommend you check out the documentationto learn more about new delegate methods, ways of controlling the widths of columnsand also how to animate alongside the transitions.The Human Interface Guidelines also explainhow split views are intended to be used.

    Now let's talk about the contents of each column.Often, you want to show lists in your primary and supplementary columns.For instance, Mail shows a list of mailboxes in the primary viewand a list of mail messages in the supplementary view.

    The modern way to show lists is using UICollectionView.It's very powerful and very flexible, and it's what we recommend going forward.There's an overview video that explains all the new API--"Advances in UICollectionView."I'm going to focus on a specific topic--getting the right appearance for the primary and supplementary columns,and I'll give you a recipe to follow.Let's dive into how to set up a collection view.This will be similar for all lists,but we'll work through an example that has items that are kinds of weather.Each item shows an image and a title.We do this setup once when we create the collection view.To make the collection view, we need a layout.That specifies the details about how the items are arranged in a vertical list.And we make a layout based on a list configuration.That specifies the default appearance of cells,whether there are headers and footers and other details.When we write the code, it's from the inside out.First we make a list configuration.That's a UICollectionLayoutListConfigurationusing the sidebar appearance.There are other appearances and properties you can change,but start with the defaults.

    Then make the layout a UICollectionViewCompositionalLayoutusing the list method, which makes it a simple, vertically scrolling list,and it's based on that configuration you already created.Finally, create the collection view and give it the layout.We do all of this once, and we don't have to touch it again.

    Next, we connect your data to the contents of the cells in the list,and this is where the details of your app come in.In this example, I have a simple structure called MyItem.It contains a title and an image,and my data store is an array of these structures.Here's one instance of it where the title is "Sunny"and the image is a system image showing the sun.Now we need some code to take an instance of this structureand show it in a cell.There's a new simple method in iOS 14.You create a CellRegistration.That says that given a cell of a certain type and data of a certain type,here's the code to run to put the data in the cell.For a list, you want the cell type to be UICollectionViewListCell.There are a lot of possibilities for how this cell can look.It's very general. The way we're setting up the content,it will contain an image view and a label next to each other.I'm showing question marks right now because we haven't filled them in yet.The data type is up to you. In this example, it's MyItem.Now let's fill in the code.

    We make a cellRegistration with those typesand give it a closure to run.The closure's given the cell, the index path on the collection view and the item.Next we use the new contentConfiguration APIto specify the cell contents.There are several built-in content configurationsfor different looking cells,but usually you want to use the default for the cell.We just take our item's propertiesand transfer them into the content configurationand then, finally, apply that content to the cell.

    When your code is called, it fills in the cell, and you see the results.

    Finally, we'll connect the last piece--make a UICollectionViewDiffableDataSource.This tells the collection view what items to show,and it's based on your data store.You push items from your data store into it.Then the data source calls its closure to create cells to display.

    There's a lot going on here, but all lists will follow the same pattern.Create the data source providing a type for the sectionsince collection views can contain multiple sections.Each section has items of type MyItem.This data source is initialized with a specific collectionView.When the data source wants a cell,this closure is called with an index path and an item.You need to return a cell.

    You call dequeueConfiguredReusableCellusing the cell registration you created earlier,and it's responsible for setting up each cell.Everything else is handled for you,including all the details of reusing cells for good performance.

    This code will be the same for most lists.The interesting parts are the type of your item and the cell registration.

    Here are the results.Nice lists with the right appearance.Note that we automatically adjust the background color for selected cellsto be different in each column.All of this appearance is customizable.Every one of those objects we created earlierhas properties that you can change.For example, when you're showing a list of content, not navigation,you want to use a slightly different appearance in the supplementary column.Use the appearanceSidebarPlain when you set up the collection view.You see the different look. The background is white,there are separators and other subtle differences.The Human Interface Guidelines say that if you have a list of content,like items in a collection or folder, then use the sidebar plain appearance.This is very common in the supplementary column.With Collection View, you can do a lot more.Here are some examples in Mail and Files.You can add accessories like check marks.You can reorder items by dragging them.You can use the outline featuresto collapse and expand items in a hierarchy.And you can add swipe actions to rows, for example, to remove a folder.

    If you're still using UITableView,we highly recommend you switch to UICollectionView.

    That makes it easy to add all these featuresand get all the new styles and appearances.

    Last, let's talk briefly about reducing modality.

    In iOS 14, we tried to get the interface out of the wayin some common scenarios.

    This reduces the amount of tapping around you need to do to get your tasks done.

    In Notes, we've made the interface more fluid.I'm bringing up the color picker to choose a color for my marker.

    And then I just draw in the document.It automatically dismisses the color picker.

    I didn't have to tap once to dismiss the popoverand then touch again to start drawing.

    All of those extra taps used to add up.

    Here's another example.I'm in Contacts and I press a button to show a menu.Traditionally, at this point, we'd put up a dimming view.But then we would require you to tap outside the menu to dismiss it.Now, in iOS 14, touching outside the menu dismisses itand you can keep scrolling with that same touch.

    We implemented that in UIKit, so you get it automatically.

    We encourage you to do similar things in your app.Every app is different, so we don't have an exact recipe.But we do suggest, watch for user actions like incoming events or scrolling,and use them as a signal to dismiss any transient UI that might be in the way.

    Now you know how to use multiple columns and Lists,and you understand how we've reduced modality.The Shortcuts app adopted all of these, and we think it's a great example.

    With that I'll hand off to Natalia to explain how Shortcuts did it.

    I'm going to tell you about how the Shortcuts appwas redesigned for the iPad.What you learn here today will help youbuild a great iPad experience for your users.Let's dive right in.

    This is Shortcuts on the iPad.We redesigned it to take full advantage of the large iPad display.For better navigation, we replaced the tab bar with a sidebar.

    This enabled us to provide more navigation options.And since the sidebar is collapsible, the display becomes customizable.Let me tell you more about how we did it.

    As Kurt said before, the Split View Controlleris the driving force behind the multi-column layouts.

    So, first I'm going to tell you how we redesigned Shortcutsusing the new Split View Controller API.

    Then I'm going to talk more about the sidebar.You will see all the parts that it's made of.By the end of this talk, you'll have a good ideaof how these new UIKit APIscome together to create a great iPad experience.

    First, let's look at the Split View Controller.

    Split View Controller is the backbone of Shortcuts.It's the API that allows usto have these two different view controllerscoexist side by side.

    On the left is what the Split View refers to as its primary column.In Shortcuts, that's the view controller driving the navigation.Whenever we tap on one of the cells there, the view controller on the right changes.And the view controller on the right is known as a secondary column.Let's see how to set up this layout in code.

    First, we initialize a Split View Controller.

    In iOS 14, we get access to this new initializer that takes in a style.

    That style describes how many columns we want to show in the Split View.We want our layout to have two columns,so we're passing doubleColumn into the initializer.

    If we wanted to have three columns instead,we would simply pass in a tripleColumn style.

    Next, we need to set view controllers that will show in each column.

    In the primary column, the one we saw on the left,we want to see a sidebar,and a sidebar is just a view controller with a few specific styles.

    That's what our Sidebar View Controller is,and we're going to use that in the primary column.We do that by calling setViewController for primary.

    Then the secondary column.And this one's a bit different since we want it to be dynamic.Whenever we tap on one of the cells in the sidebar,we want to update the secondary column.

    So, first we need to know when the cell is selected so we can react to it.And for that, we conform to UICollectionView delegateand implement didSelectItemAt indexPath.Then, we show the DetailViewControllerin the secondary column by calling showDetailViewController.

    So now we have the Sidebar View Controller in the primary columnand the Detail View Controller showing on demand in the secondary column.

    Now, this is great for the iPad,but we also redesigned Shortcuts on the iPhone.There we didn't have space for two columns,so we implemented an entirely different layout.

    In compact width, we have a tab bar in the list view,so the navigation options that were in the sidebar in regular widthare split between the tab bar and the list view in compact width.Now, this is a very different layout.But what we're looking at hereis using the same UISplitViewController API that we just talked about.Let's see how that's possible.

    Aside from the primary column and the secondary column,UISplitViewController also has a notion of compact column,and that's the column that we see when the device is in compact width.And so, just like with the other columns,we simply call setViewController for compact,and the compact layout is done.

    This is really powerful because we're free to establishour own separate compact flow,but we don't need to worry about switching between layouts.All of that is done for us by the Split View Controller.

    The one thing to know about using this approachis the fact that we are working with two separate view hierarchies,the one in regular width and the one in compact width.So while the Split View Controller knows which hierarchy should be usedbased on the current trait collection,we need to make sure that the user is in the right placeas the size classes change.Let's look at an example.

    Let's say we open the app and navigate to the Apple Watch folder.Then we decide to open another app in side by side.

    That causes the Shortcuts app to movefrom regular width to compact width.And without us doing anything, the Split View Controllerdisplays the compact hierarchy, which is great.But that's not the hierarchy we just navigated.So by default, it will put us back at the beginning of the flow.

    So, we need to make sure that these transitions are smooth.Here's how we're doing it.

    The Root View Controller is the parent of the Split View Controller.

    That's where all the navigation happens.Each Detail View Controllerthat can be displayed in the secondary columnconforms to a protocol,and that protocol requires the view controllerto provide a method that re-creates it.When the size class is about to change,we look at the current Detail View Controllerand re-create it using the protocol method.

    Once we do that, we plug it into the new view hierarchy,and that's how we make sure the state is restored.Let's talk more about the sidebar.

    Now we know that the sidebar is just a view controllerwith a few specific styles.But let's take a closer look.Here's the sidebar.You can clearly see there's a large title,a left bar button that let's us collapse the sidebarand a right bar button that toggles the editing mode.But what's inside of the sidebar?It's a collection view filled with new list cells.Let's look at the code, starting with the collection view layout.

    The Sidebar Collection View is using compositional layoutwith the default configuration.The one thing that stands out is the sectionProvider.The sectionProvider allows us to configureevery section in the collection.The section we are providingis using the new ListConfiguration with the sidebar appearance.And that pretty much sets up the layout for us.The section itself is a new list section.We pass in the configuration and we're done.This is the entire layout.Now let's look at the cells.

    First, we need to set up our cells.We're used to registering the cells for later dequeuingby calling Register on the collectionView.With the new cell registration API, there's a new way to do that.

    We can register and configure the cells in one placein a type safe way.We don't need to worry about keeping track of forUse identifiers anymore.We just set up cellRegistration and pass it directly into the data source.

    So this is how we register the cells.Let's see how we configure them.

    In the past,whenever we wanted to make collection view cells nice and custom,we would end up creating a subclass.We don't need to do that anymore.And that's thanks to the new UIContentConfiguration API.We can mix and match configurations to get the cells exactly as we want them.We can create completely custom configurationsor we can take advantage of existing premade configurations.For example, here we're simply usingthe predefined defaultContentConfiguration.This returns the default configuration with sidebar cell stylingas the cell is contained in a list with sidebar appearance.So we're just setting the title and the image,and everything else is taken care of.

    So that's it for Shortcuts on the iPad.

    Great iPad apps allow usersto take full advantage of the beautiful, large display.So try adding a sidebar to your iPad app and be creative.If your content needs more than two columns,use a supplementary column.

    Use collection views with predefined configurations.Collection views are much more powerful than table views,and predefined configurationsare an easy way to add functionality and polish to your app.

    And finally, get the interface out of the way.Lean on gestures and enable users to move within your app freelywithout the interruption of modals that take up all this space.And remember to check out the links attached to this video.There's so much more to learn about these new APIs.

    Thank you for watching.We can't wait to see your appsbuilt for iPad.

    • 1:57 -Create two column UISplitViewController

      let splitViewController=UISplitViewController(style: .doubleColumn)
    • 2:13 -Set view controllers for primary and secondary columns

      splitViewController.setViewController(sidebarViewController, for: .primary)splitViewController.setViewController(myHomeViewController, for: .secondary)
    • 2:28 -Create three column UISplitViewController

      let splitViewController=UISplitViewController(style: .tripleColumn)
    • 2:29 -Set view controller for supplementary column

      splitViewController.setViewController(inboxViewController, for: .supplementary)
    • 4:02 -Set view controller for compact column

      splitViewController.setViewController(tabBarController, for: .compact)
    • 5:29 -Set preferredSplitBehavior to .tile

      splitViewController.preferredSplitBehavior= .tile
    • 5:44 -Set preferredSplitBehavior to .displace

      splitViewController.preferredSplitBehavior= .displace
    • 5:51 -Set preferredSplitBehavior to .overlay

      splitViewController.preferredSplitBehavior= .overlay
    • 5:56 -Hide and show columns

      splitViewController.hideColumn(.primary)splitViewController.showColumn(.supplementary)
    • 6:08 -Set preferredDisplayMode

      splitViewController.preferredDisplayMode= .oneBesideSecondary
    • 8:06 -Collection view setup for sidebar list

      let configuration=UICollectionLayoutListConfiguration(appearance: .sidebar)let layout=UICollectionViewCompositionalLayout.list(using: configuration)let collectionView=UICollectionView(frame: frame, collectionViewLayout: layout)
    • 8:38 -Define a type for an example data structure

      structMyItem:Hashable{let title:Stringlet image:UIImage}
    • 9:36 -Create cell registration

      let cellRegistration=UICollectionView.CellRegistration<UICollectionViewListCell,MyItem> { cell, indexPath, iteminvar content= cell.defaultContentConfiguration()    content.text= item.title    content.image= item.image    cell.contentConfiguration= content}
    • 10:31 -Create diffable data source

      let dataSource=UICollectionViewDiffableDataSource<Section,MyItem>   (collectionView: collectionView){ collectionView, indexPath, iteminreturn collectionView.dequeueConfiguredReusableCell(using: cellRegistration,                                                        for: indexPath,                                                       item: item)}
    • 11:29 -Collection view setup for sidebar plain list

      let configuration=UICollectionLayoutListConfiguration(appearance: .sidebarPlain)let layout=UICollectionViewCompositionalLayout.list(using: configuration)let collectionView=UICollectionView(frame: frame, collectionViewLayout: layout)
    • 15:35 -Example: Initializing UISplitViewController

      let splitViewController=UISplitViewController(style: .doubleColumn)// Primary columnlet sidebar=SidebarViewController()splitViewController.setViewController(sidebar, for: .primary)// Secondary columnfunccollectionView(_collectionView:UICollectionView,didSelectItemAtindexPath:IndexPath) {    splitViewController.showDetailViewController(DetailViewController(), sender:self)}
    • 17:50 -Example: Setting a view controller for compact width

      let tabBarController= createTabBarController()splitViewController.setViewController(tabBarController, for: .compact)
    • 20:39 -Example: Sidebar Collection View setup

      let layout=UICollectionViewCompositionalLayout(sectionProvider: sectionProvider,         configuration:UICollectionViewCompositionalLayoutConfiguration())funcsectionProvider(_section:Int,environment:NSCollectionLayoutEnvironment)->NSCollectionLayoutSection {var configuration=UICollectionLayoutListConfiguration(appearance: .sidebar)if (environment.traitCollection.horizontalSizeClass== .compact) {        configuration.headerMode= .firstItemInSection    }else {        configuration.headerMode= .none    }returnNSCollectionLayoutSection.list(using: configuration, layoutEnvironment: environment)}
    • 21:13 -Example: Cell Registration

      structSection:Hashable{ }structItem:Hashable{ }let cellRegistration=UICollectionView.CellRegistration<UICollectionViewListCell,Item> { cell, indexPath, itemin// Configure the cell}let dataSource=UICollectionViewDiffableDataSource<Section,Item>(collectionView: collectionView) { collectionView, indexPath, iteminreturn collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: item)}
    • 21:48 -Example: Cell registration

      let cellRegistration=UICollectionView.CellRegistration<UICollectionViewListCell,Item> { cell, indexPath, iteminvar content= cell.defaultContentConfiguration()    content.text= item.title    content.image= item.image    cell.contentConfiguration= content}