navigate site menu

Start learning with our library of video tutorials taught by experts. Get started

iOS 6 SDK New Features

iOS 6 SDK New Features

with Simon Allardice

 


Bring your existing iOS development skills—and your own applications—up to speed with the new options in iOS 6 SDK. Author Simon Allardice covers not only the new features (including collection views and APIs for Facebook, Passbook, Maps, and Reminders), but also changes in hardware and the current best practices in iOS development.
Topics include:
  • Understanding the impact of changes to Xcode and Objective-C
  • Adding and configuring the new UICollectionView
  • Dynamically changing the size of collection view cells
  • Using Auto Layout to arrange an iOS user interface
  • Creating a custom pass with the Passbook API
  • Posting to Facebook with the Social framework

show more

author
Simon Allardice
subject
Developer, Mobile Apps
software
iOS 6, Xcode 4
level
Intermediate
duration
2h 29m
released
Mar 13, 2013

Share this course

Ready to join? get started


Keep up with news, tips, and latest courses.

submit Course details submit clicked more info

Please wait...

Search the closed captioning text for this course by entering the keyword you’d like to search, or browse the closed captioning text by selecting the chapter name below and choosing the video title you’d like to review.



Introduction
Welcome
00:03Hi, I am Simon Allardice, and this is iOS 6 SDK New Features.
00:08If you have been developing for iOS devices but working with the features in iOS 5 and
00:13before, this course will quickly bring you up to speed on what is available in iOS 6 and how to use it.
00:18We'll see the changes to user interface controls in this version of iOS, particularly collection views and what they offer.
00:25We'll also explore the changes and improvements in Xcode.
00:28Things like using Auto Layout for your user interfaces and the current best practices
00:33when creating classes and properties in Objective-C.
00:36We'll see how to create apps that use Apple's new Maps features, or how to use passbook
00:41in your own applications for managing passes, tickets, or coupons, see what the
00:47social framework offers for Facebook integration.
00:48So, let's get started with our look at the new features of the iOS 6 Software Development Kit.
Collapse this transcript
What you need to know
00:00This is a new features course for version 6 of the iOS SDK.
00:04So, this is meant to bring you up to speed if you've already been developing iOS apps using iOS 5 SDK.
00:11And you need to have that knowledge if you want this course to make sense.
00:14You know your way around Xcode, you can read and write Objective-C, and you're familiar
00:18with the core skills of iOS development like working with Model-view-Controller, Delegation,
00:22and Target-Action, and I do expect you to be comfortable with the major developer features
00:27of iOS 5 like Automatic Reference Counting and Storyboards.
00:31Now, if you need to first learn these skills or even just brush up on your knowledge, take
00:36a look at our other courses at lynda.com first, like the courses on Objective-C, or iOS SDK Essential Training.
00:43But if you are ready to go, then let's start exploring this version of the iOS Software Development Kit.
Collapse this transcript
What we'll cover in this course
00:00I am recording this course using iOS 6.1 and Xcode 4.6, both released at the very end of January 2013.
00:09As ever, Apple do release new versions of Xcode and iOS on a regular basis.
00:14So if you're using a newer version, you may see some slight differences.
00:17What you don't want is to have any earlier version than I do.
00:21So if you open up Xcode and see version 4.5 or earlier, make sure to update Xcode before continuing.
00:28If you've been following the progress of iOS development over the last few years, you'd
00:32know that with every major number release of iOS to the general public, we've also had
00:37big changes to the SDK, and we only have a few years of this.
00:41After all, version 2 of the operating system iPhone OS 2 was the first version where developers
00:47outside Apple could create apps at all.
00:50But quite quickly, we had version 3 and then version 4 of the SDK.
00:54Now, version 4 brought multitasking and added blocks to the Objective-C languages.
00:59These were both very big changes for developers who started on OS 2 and OS 3.
01:05And then iOS 5 came along and gave us the wonderful Automatic Reference Counting,
01:10or ARC, as well as Storyboards.
01:11And once again, these were big sweeping changes, things that every iOS developer needed to understand.
01:18But iOS 6 doesn't have anything on the same level as the addition of ARC or the switch to multitasking.
01:25There's simply nothing that impacts every iOS project on that same scale.
01:29What we have this time around are several new frameworks.
01:32Now, we always get new frameworks, iOS 6 is no exception, and a few smaller things that
01:36do improve the overall programming experience.
01:39AutoLayout, it's a new way of arranging iOS user interfaces.
01:43It is probably the most noticeable if you're coming from iOS 5 to iOS 6, but it's nowhere
01:48near as bigger change as say Storyboards were going from iOS 4 to iOS 5.
01:54The most substantial additions in iOS 6 are the new feature-focused frameworks, PassKit, and the Social Framework.
02:01Now, here is the issue with creating a course on those frameworks.
02:05You may or may not care about any of them, and that's perfectly okay.
02:09Those kinds of frameworks aren't about general iOS development, they're very specific to a need.
02:14You use them if you want that feature, you would know them if you don't.
02:18So you for example maybe totally enthused about Facebook integration for your app or
02:23it may be completely irrelevant to you, same with integrating maps or working with passbook.
02:28So to keep everything useful and relevant here,
02:31what I am going to focus on in this course is not trying to make you an expert on any
02:34one of the new frameworks, but just to make you a good all round iOS 6 developer.
02:39You understand them all, and not just at a simple sentence level, but you've had a hands-on
02:44example of what the new major frameworks cover and how you'd get moving with them,
02:49and if and when you need to go deeper, you know exactly how to do that.
02:52And we'll cover in more depth things like AutoLayout and the new user interface controls
02:57like collection views, things that you are more likely to use in all your iOS development going forward.
03:03So, before we get into those frameworks, we're going to start with those changes, additions
03:06to Xcode and new and improved controls for the iOS user interface.
Collapse this transcript
1. Xcode and Objective-C changes
Changes to Xcode
00:00The previous major release, iOS 5, was released along with Xcode 4.2, and there were
00:06a few point releases of Xcode during 2012.
00:09We had 4.3, 4.4, 4.5, as well as a few others in between.
00:14But rather than just talk about what's new specifically in Xcode 4.6, and there really
00:20isn't a lot new in 4.6, I am going to cover the changes that have happened in Xcode since
00:25the release of iOS 5.
00:26So if, for example, you had watched the iOS SDK Essential Training
00:31or Objective-C Essential Training courses, a lot of those were recorded using Xcode 4.2 and 4.3, I am going to get
00:38up to speed on what has changed in Xcode since then.
00:42Now, Apple often go into excruciating detail on the Xcode changes between versions.
00:48We don't really need to do that. We just need to clear the decks.
00:51So, even if you have been working with 4.4, 4.5, 4.6, I'm just going to go through
00:57and cover the two or three major impacts of each version.
01:01And over all the changes that have happened, I am only going to have three things that
01:04are big enough to talk about on their own. So Xcode 4.3 arrived.
01:09This was the one that turned Xcode into a regular App Store application that just installed
01:14into your normal Applications folder on your Mac.
01:17Before that, we needed a separate installer application for the SDK, and it installed
01:22all the tools at a different location, and really, that was the main change
01:27of Xcode 4.3, there wasn't a lot new there.
01:29Although it did mean that you had to now open other developer tools like Instruments say
01:34from within the Xcode menu because they weren't installed as totally independent applications
01:40as they have been previously. Then we got Xcode 4.4.
01:43A couple of good things here, 4.4 didn't change much visually, but it uses a new version of
01:49the LLVM compiler, version 4, behind the scenes, and that supports a couple of shortcuts of
01:55efficient ways of writing Objective-C to save us some time, first, Objective-C Literals.
02:02We've long been able to use the at sign as a shorthand to create an NSString object,
02:07but now we can use that also to create NSArrays, NSDictionaries, NSNumbers.
02:12We don't have to use some of the more tedious init methods to create these.
02:17I am going to cover literals in their own movie in just a minute.
02:20Now also with Xcode 4.4, synthesize happens by default.
02:25You don't have to write synthesize statements for your properties anymore.
02:29This was a technically minor change, a minor improvement just to kind of get away some
02:35speed bumps in the road, but it did trip a lot of people up, particularly developers
02:39new to the Objective-C world, because it meant there was a little bit of behavior now happening automatically.
02:45But if you didn't understand what that behavior was, it wasn't clear how your properties worked.
02:50So, this is the second thing I'll talk about on its own and talk about these synthesize
02:55statements and the current best practices with them in just a moment.
02:59But first, let's finish clearing the decks.
03:01Xcode 4.5, this was the first version of Xcode to work with iOS 6 SDK.
03:08The two main points here, LLDB is now the default debugger in Xcode to bring us in line
03:13with using LLVM as the default compiler.
03:17And AutoLayout, a new layout option that had been available in Cocoa desktop development
03:22for a while is now supported and is actually the default in iOS.
03:26And AutoLayout will be the third thing I'll cover separately.
03:29And that brings us to Xcode 4.6, no huge changes here, some general improvements in the compiler and debugger.
03:38You can do things like inspecting the elements inside NSArrays and NSDictionaries and the debugger.
03:44Okay, if you're coming from another language, you might think, big deal.
03:47We've had that for years, well we didn't, and now we do.
03:51Now with improvements to the compiler and debugger, if you know you have older projects
03:56that are still set to use the older style GCC and GDB, know that Xcode 4.6 is the last version to support these.
04:04So, be aware that sometime soon, change your project settings over to LLVM and LLDB, because
04:10that is where Apple have planted their flag.
04:13Now, all new projects, everything we do in this course will just use LLVM and LLDB by default.
04:19So, I've got three things to cover here, literals, synthesize, and AutoLayout.
04:25Let's do literals first.
Collapse this transcript
Using Objective-C literals
00:00Objective-C Literals syntax is great and something that you are likely to use in everyday code.
00:05But let me be clear, what I am about to show you doesn't give you any new capability you
00:10didn't already have, but it does make it faster and easier to write code to create common objects.
00:16And you have already used this idea with NSString, if you've ever written a line of code likes this
00:22where you didn't say alloc and init or any variant of that, but you still end up with
00:27a NSString object because the at sign here is telling the compiler to go ahead and create
00:32that NSString object with these contents, it's a shortcut format to make it easier for you to create NSStrings.
00:39Now this syntax has been expanded to include NSArray, NSDictionary, and NSNumber objects.
00:46And as with NSStrings, it's all about the at sign. That is the indicator to the compiler that
00:51you are about to begin using the literal syntax. Let's see some before and afters.
00:58So I've just got some simple code here inside a basic Command-line tool, and let's take the
01:02good old NSArray on line 22 here.
01:05This is the format used by many years of Objective-C developers, creating Arrays with the method
01:11alloc and init with objects or perhaps using array with objects, and you are providing
01:16a list of those objects, although taking care to terminate that list of objects with nil.
01:21This is how you have to tell the NSArray that it's finished, that you've provided all the objects for it.
01:27And the objects I am passing here are just the ones I am creating on line 17 through 19,
01:31just basic NSString and NSNumber.
01:33Well, this is now the alternate way of creating an NSArray.
01:38I first define the pointer to it, NSArray *myArray= then I use the at sign, and I need
01:45to open up the square bracket here.
01:48And it gives me the little pop-up code sends that I just need to provide a list of objects.
01:53So I will, I have a few that I am creating on those earlier lines, and then I am done,
01:59I just close the square bracket and finish the line.
02:02I no longer need the alloc, I no longer need init with object, and I no longer need the nil at the end.
02:08Now once again, this is not a new kind of NSArray, this doesn't provide anything different, it's
02:13simply more concise, this is easier to write and easier to read.
02:16Now just as there is that syntax to create them, there is also a shortened syntax to
02:22access the elements inside an NSArray once you've actually got one.
02:26Now this is the conventional format that you're probably used to already, using the objectAtIndex method of NSArray.
02:34Well, this is the new format, name of the array and then as in many other programming
02:39languages, we can just use the square brackets here and give it the number of the element that we want.
02:44So if I want the second element, that's going to be number 1, zero based of course, again
02:49just simply a concise way to do this.
02:52Now one of the objects I am adding to this array here--this baz object--is this one that
02:56I am creating on line 19, and it's an NSNumber.
02:59Because if you just want to put say a basic primitive value like an integer or a float
03:04inside a collection, you can't. You need to box it up, you need to make it a proper Objective-C
03:09object, and that's what NSNumber is for, it's a wrapper for a primitive value.
03:14So we commonly use methods like this, creating an NSNumber with numberWithInt.
03:19Although there is lots of these methods numberWithChar, numberWithFloat, numberWithLong.
03:24Well, NSNumber gets a literal syntax too, so I want to create a new NSNumber with the integer 99.
03:30All I need to do is use the at sign and the number, and it's smart enough to understand
03:37whether we are providing an Int or a Float or a Double and so on.
03:40So for an integer, this is just like using a number with Int.
03:44If I passed in 99.345, that would be like using number with double, I'd add the F if I want
03:50it to make it a float explicitly.
03:53Now sometimes NSNumber is used to wrap a Bool primitive so you can also use Bool values,
03:59just an uppercase YES or uppercase NO.
04:02Don't need any square brackets, don't need any double quotes, we just use the at sign
04:07and the value, it's as simple as that.
04:09And finally, we have NSDictionary, a set of key value pairs.
04:13So we are not accessing the elements by number, we are accessing them by key.
04:17And there is a few different ways to create an NSDictionary, but very commonly you'd see
04:21using this method, using it together with alloc and initWithObjectsAndKeys.
04:25Now I've always found this format quite clunky and unintuitive because it is written
04:31as key value pairs, but it's written as the value-- say iOS SDK New Features--followed by the key
04:39which is kind of unusual.
04:40More conventionally across multiple programming languages, it's key then the value.
04:45So I am providing four sets of key value pairs here, and then you also have to terminate
04:52an NSDictionary with nil.
04:53There is going to be a lots of problems if you don't do that.
04:57So let me comment that one out and show you the new way of doing it now.
05:06Once again using the at sign, but this time we are not using the square brackets, we are
05:10using the curly braces, and if you see the pop-up here, I can see the close to this literal syntax.
05:15We've got the NSString is using the double quotes, we've got NSArray is using the square
05:20brackets, and we've got NSDictionary is using the curly braces with pairs of keys colon object comma.
05:28So we just give it repeating pairs of keys and values.
05:32I'll just scroll up to give myself a bit more room here, and I'll split this across lines
05:36so it's a little more readable.
05:42And this is the new NSDictionary literal format, it's using the key then the value,
05:47the more conventional way to write these, and I just provide pairs of these.
05:50All right, so I am just going to paste in a little code here.
05:56So I've split these on multiple lines so they are more readable, I am just giving it multiple
05:59pairs of keys values, here I am actually using the NSNumber literal syntax to just pass in
06:05directly the number 2013 and a Boolean value of YES.
06:09We have the closing curly brace, and we finish the line.
06:12As with the NSArray literal format, a nil is no longer needed to terminate the NS dictionary.
06:17We just finish writing the key value pairs.
06:20And also adds with NSArray we have a shorter way of getting to the values inside there.
06:25This is the conventional way of accessing an element in an NSDictionary, we use the
06:30value for key method, and this is the new way.
06:36The name of the dictionary and while we create it with curly braces, we access the elements
06:41using the square brackets, the subscript operator.
06:45Same is with an array and same is in many other languages, and I just provide the key
06:50to that element, so author for example.
06:54And this could be a separate independent NSString object. I am just using NSString literals for the sake of time.
07:04So if I go ahead and run it, well, I see I am actually mismatching my own values here,
07:07I am saying the title is but also writing out the author, so let's try and pass
07:13in a different key, and that's what I'd expect to see here.
07:18So to summarize NSString literal format which you've used before is the at sign and the double
07:25quotes, whatever you want inside that.
07:28The NSArray is the at sign and the square brackets and your list of objects inside that,
07:34the NSDictionary is the at sign and the curly braces, and the NSNumber is just the at sign and the
07:39primitive value that you want to box up.
07:41And one thing worth mentioning, when I say they've added the syntax for creating NSArrays
07:46and NSDictionaries and NSNumbers, I don't mean those classes and all the other things
07:51just like them like NSSets and NSMutableArrays. No, those don't support this format.
07:56It is just NSArray, NSDictionary, and NSNumber, at least for now.
Collapse this transcript
Current usage of @synthesize
00:00When defining properties in your classes like this very simple Objective-C class I have
00:05here, it became common behavior for Objective-C developers for many years to get into the following habit.
00:11You'd write the property and define it in your interface and your header file, and then
00:15you jump over into the implementation, and you would match it up with a synthesize statement over there.
00:21And what this would do is tell the compiler to synthesize or generate the instance variable
00:27for each of these properties and also create the standard accessor methods, a getter method
00:32and a setter method for each property. Well, you no longer need to do the synthesize.
00:37As of Xcode 4.4, writing the synthesize statement is now optional.
00:41So if you've defined the property, and you don't write the synthesize statement or provide
00:46any other custom code for that property, the compiler will just automatically synthesize by default.
00:52However, it's worth understanding a little more about what the effect of this is.
00:58Because if you were previously in the habit of writing simple synthesize statements,
01:02like this where I've got synthesize name and synthesize hireDate to match my properties and my header.
01:07And this for simplicity is what I typically show in my courses.
01:12What this would actually do, say in the case of hireDate is it would synthesize three things.
01:17An instance variable called hireDate, a getter accessor method which had exactly the same
01:23name, hireDate, and a setter method which would just put the set word in front of it, so set hireDate.
01:30But if I delete this line and let automatic synthesis happen, I may run into a problem,
01:37because the automatic synthesis behavior that's provided by Apple--or rather provider
01:42by the compiler--is not exactly the same as just writing synthesize hireDate or synthesize name.
01:48It's more the same as if I've written this, @synthesize hireDate = _hireDate.
01:55Now what this format means for synthesis is that the synthesized instance variable internal
02:02to the class would have the leading underscore.
02:04The getter and setter methods will stay the same, hireDate and set hireDate.
02:09So what happened if I was using either that format manually or leaving it off entirely
02:14which is exactly the same as writing that is it's complaining down here but I am trying
02:19to use the format that suggests I am looking for an internal instance variable,
02:23and it no longer has that name.
02:25I could actually use _hireDate, but that kind of reveals a problem.
02:29I should really use the proper accessor method instead of trying to directly get to the instance
02:35variable, even internally inside this class.
02:38It would be much better practice to either use self hireDate, the name of the actual
02:44getter or alternatively I could use .syntax, which would also use the accessor method.
02:53And if I got rid of the other synthesize, we'd have exactly the same problem here, showing
02:57me that I was using the name of the instance variable but that now would have an underscore
03:01in front of it can I could use the underscore, but it's the best practice that I would actually
03:06use the proper accessor method.
03:10So with auto synthesis, if you just let the compiler do it--and I suggest you do--
03:16just know that your instance variable for that property will be named with a leading underscore,
03:21but you should be really using the accessor methods to get to it anyway.
03:25Beyond that little gotcha, nothing has changed.
03:28If you need to create non-standard getters and setters, you can still do that by simply
03:33providing your own getter and setter methods.
03:36But this is the behavior that you'll get if you just define your property and let automatic synthesis happen.
Collapse this transcript
Creating an iOS user interface with Auto Layout
00:00Autolayout was first added to Xcode in 2011, but at that time it was only for Mac desktop
00:06development, not for iOS, and it's an improved way of how controls on user interfaces can
00:11arrange and resize and lay themselves out, and it replaced the older technique called struts and springs.
00:17Now with the release of iOS 6 Autolayout is also the default method for iOS user interfaces,
00:24and it's what we're using in this course.
00:26So I'm going to create a classic Single view iOS Application. I'll just do this for iPhone and use Storyboards.
00:34It doesn't matter if you use storyboards or stand-alone XIB files, it'll work the same.
00:39Autolayout is used in both.
00:41So if I go ahead and create this and then jump into the Storyboard, at first glance
00:46it doesn't look any different from what we might have seen in several previous versions of Xcode.
00:51But if I select the view Controller--I'll just click the status bar to see the big blue surround--
00:56go over here to the File inspector, the first one,
01:00I should see this check box here to Use Autolayout, so this is the default now.
01:05Now if I turn that off, there is no visible difference to this.
01:09Although I can see down at the bottom of the canvas that I'm getting a few extra buttons
01:13turn up when Autolayout is enabled.
01:16But the best way to demonstrate Autolayout is to first kind of compare to what we had before.
01:21I can do that by just turning this off for a moment.
01:24This is going back to the old way that we've had in Xcode for several years.
01:29So I turn off Autolayout, I'm going to go into my object library here and just drag on a few buttons.
01:35Position this one at the top left, position another one at the top right.
01:40Again, this is standard stuff, nothing new here.
01:45And drag on a third one, and I'll put it into the center.
01:48We see the usual guidelines to help us put something in the center or connect it to the
01:54left and still keep it a certain gap away from the suggested iOS guidelines here.
02:00Very simple interface, I'm just going to hit Command+R to run this.
02:04It opens up in my simulator here, and we've got immediate couple of problems.
02:08First, the bottom button has completely disappeared the way I'm looking at it now.
02:12Secondly if I change this orientation to landscape, the button that currently says top right is
02:17positioned well more towards the center, when I'd really want to move it towards the right.
02:23So the reason that the bottom button has disappeared is because I go back into the design here,
02:28what I'm looking at is the default view controller layout which is actually for the iPhone 5,
02:34the longer orientation, the 4-inch screen, but my simulator was set up to run with the
02:38older style iPhone with just 3 & 1/2 inches, so it's disappearing off the bottom.
02:43So I'm using the old way of laying this out, and I could still fix this.
02:47What I have to do is go into the size inspector over here, selecting the different elements,
02:53and let's stop manipulating the struts and springs that we'd see in the Autosizing section
02:58to make sure that for example this button was not hooked up to the top, but it actually
03:03had a strut connecting it to the bottom.
03:06Struts and springs are like physical idea of struts and springs in architecture or automobiles.
03:10A spring is something that can expand and contract and a strut is something solid with a fixed width.
03:16So I could select this top right button which currently has struts connecting it to the top on the left.
03:21What I'd really want is struts connecting it a fixed width to the top and the right,
03:26I can see the little highlight that it should be dragged to the right as this screen either
03:31resizes, while we don't resize on iOS, but we do change with orientation.
03:37If I'd worked with the springs, which are the things inside the box, we'd see it actually grow and shrink.
03:42But I'm just going to turn on a couple of struts there and go ahead and run this again.
03:48This looks better, we at least have the bottom button turning up, and if I switch into landscape
03:53view, this is a bit more what we'd want.
03:56So I can still fix it the old way using struts and springs.
04:01But Autolayout as you'll see in a moment is a better way, and it usually works better
04:05right out of the box without any manipulation.
04:09So I'm going to switch back, so I'm going to switch this back into Autolayout.
04:12So selecting the actual view controller itself, I'll make sure I have the blue bar here, jump
04:16into the File inspector, the first one, and turn on Autolayout.
04:20Now I could keep these controls where they are, but I'm just going to delete them all
04:24just to kind of re-add and prove that they work differently and drag on a couple of buttons again.
04:30Nothing remarkable here, I'm still getting the guidelines, I can change the text of this button.
04:35If I didn't know better, I'd think it was exactly the same.
04:40But the important thing is happening, and here's what's important about Autolayout.
04:44It's not about us dragging on these buttons, it's not about these guidelines, Autolayout
04:48is all about what happens when I let go.
04:50And if I let go of this button that's kind of guided to the top and the right, what I'll
04:55see is two lines appear over here on the top and the right.
04:59These are what are referred to as constraints, and Autolayout is all about constraints.
05:05They describe a relationship between two visual elements, two views.
05:09So we can have a constraint between a button and the top of the view that it's contained
05:14in or a constraint between the right-hand side of the button and the right-hand side
05:19of the view that its contained in.
05:20You can also have a constraint between two elements of the same level.
05:24So if I drag another button beneath this one, we get a little constraint is appearing--
05:29little difficult to see there-- but between the two buttons.
05:33Constraints are actual objects in Objective-C, it's the NSLayout constraint objects.
05:38They're added by interface builder as we edit our XIB files.
05:42You can also manually write them in code, but that's not what we're going to do in this course.
05:45So when Autolayout is turned on, if you click a user interface element like a button,
05:50you will see all the constraints that are attached to that object.
05:55You can then actually click the constraint itself, sometimes a little difficult to click
05:58because they are so small and an amber highlight will appear to show you what objects that constraint applies to.
06:05Now as a side note, it's a common gotcha when you're new to Autolayout to accidentally have
06:09a constraint selected when you think you have a button or something else selected.
06:13So if you see the amber highlight, know that you have a constraint selected, you don't
06:17want to be trying to Ctrl-drag from a constraint into our code file when you think you're Ctrl-dragging from a button.
06:25So constraints highlight in amber, regular UI elements highlight in blue as they have done always.
06:30Now you can also get to these constraints using the dock or the jump bar.
06:35If I open up this doc here I'll see there is a section called constraints, and I can
06:39drill through each individual one.
06:41You see there are different kinds of constraints here, vertical space, or horizontal space constraints,
06:46they're highlighting as I click around them.
06:48And selecting each one will show you which elements it applies to.
06:53If I drag another button down here towards the bottom, and I want to position it in the
06:57center, if I use these guidelines here, I'll get another kind of constraint,
07:02a Center X Alignment constraint, that they are actual first-class objects in Objective-C.
07:07Now if I select any of these user interface elements and then jump into the Size inspector
07:11where we used to see struts and springs in the Autosizing section, we don't see that
07:16anymore but we will see a Constraints section if that element has constraints on it.
07:21So it's telling you I have a constraint in the top space to the button above it and in
07:25the trailing space which means the space to the right-hand side to the Superview, Superview
07:30meaning the container that this is sitting in the actual window view.
07:34And when you actually select a constraint itself, you can even edit it in the Attributes inspector.
07:40It's a true object like all other objects are.
07:44Here's the thing, most of the time you don't add constraint yourself, you let Xcode
07:49do it as you're setting out your interface.
07:54And Xcode makes a really good guess where the constraint should be added.
07:58As you move elements around, it tries to create the minimum number of constraints based on your arrangement.
08:03If you drag to the left-hand side, you'll get a constraint between the left-hand side and the top.
08:08As I stop moving towards the bottom, it thinks that it's more important to have the constraint
08:13between the bottom and the left-hand side.
08:16If I move it underneath another element, it assumes that the constraint that's important
08:21here will be a constraint between the two elements.
08:25Sometimes you have to drag or re-drag an element around to get the constraint that you're expecting,
08:30but you can usually get it.
08:31Now I've got too many buttons here, so I'm going to drag on something a bit more interesting like a Text view.
08:41The guidelines are still very useful and they will help you in adding those constraints,
08:45so I'm dragging this one down, waiting to see it snap near the button, and that should do it.
08:51Go ahead and test this again, seems okay in portrait, and it also seems okay in landscape.
08:59However, I actually don't even need to wait that long, I don't need to run it to see this
09:03because the Autolayout impact is visible in the designer itself.
09:07If I selected the entire view controller just by clicking status bar, jump over here into
09:11the Attributes inspector, I can change the orientation to landscape and those constraints
09:16will take effect here as well.
09:19So what you're hopefully noticing is Autolayout is working pretty well straight out of the box.
09:24I don't have to change anything the way that I had to change things with struts and springs
09:29just to make even a very basic layout like this work the way I typically want it to work.
09:34So let's do something a little bit more involved.
09:37I am going to imagine that perhaps this screen is a terms of use that somebody has to agree on.
09:42I have to click a button that says Yes, which is right there in the center, and then
09:46I'm going to put another button beside it to say that they disagree.
09:51So drag on this button, I'll use the snapping guidelines to give me the right size and give
09:56it a long title like, No, I totally disagree.
10:00Now perhaps you'll notice that as I did that it did resize the button the way that you'd
10:07hope it would, but it is keeping it to the right-hand side of this Yes button, because
10:11yes was dragged to the center and has that Center Constraint which is regarded as important.
10:16So I'm going to go ahead and run this again, and it opens up in portrait view and really
10:23doesn't look all that good.
10:24That button is moving off to the right-hand side.
10:27The reason for this is that the only constraints we actually have down here is that
10:32the Yes button has to be in the center and then there is another constraint in between the buttons
10:37to say that the No, I totally disagree is to the right of it.
10:41There is no constraint on the right-hand side of this button, so there is nothing that would
10:46stop it from moving off the side of the screen.
10:49Now there are of course multiple ways I could arrange these buttons, I'd probably just drag
10:53them to the right-hand side and make a constraint appear on that right-hand side,
10:58but let's say what I've decided I really want this Yes button in the center where possible, but only
11:04as long as it's not pushing the disagree button off to the right.
11:07Well, I can do that, I just need to play a little bit with some manual constraints.
11:12So I can add a manual constraint to the right- hand side of this disagree button, what's referred
11:17to as the trailing side.
11:19Again by selecting the button I see all the constraints that are currently here, there
11:23is one connecting it to the next button, there is one hooking it up to the bottom, but that's it.
11:28So here is how I connect one on this side, I create a new manual constraint.
11:32With that selected, I go to the Editor menu, come down to Pin, and what I'm looking for
11:37is this option, Trailing Space to Superview.
11:41Trailing space is the right-hand side of this element, Leading Space would be the left-hand
11:45side, Top Space is the top of the element, Bottom Space the bottom.
11:48And we're doing it to the Superview because it's the container, it's the window that this is inside.
11:53So I click that, and you will see the constraint appear on the right-hand side.
11:57All right, let's see what impact that has.
11:59I'll run it again, and we're still having problems here.
12:05It's not moving off the right- hand side, but it's not a lot better.
12:09If I just perhaps have the word no, it might be fine.
12:11Here is what's happening, the three constraints that we have are saying have this yes button
12:16in the center, have a gap between the buttons, and have a gap between the right-hand side
12:21of the button and the right-hand side of the screen.
12:24So the only thing left to do is shrink the button, which is what iOS is doing.
12:29So not really what I wanted. What might we do here?
12:32Now the reason for that happening, if I select that right-hand constraint here and go to
12:38the Attributes inspector, what it's telling me is this constraint is a horizontal
12:42space constraint, no surprise there. But we've got a few options here.
12:46What's happening is it's saying this is a space constraint that must be equal to a Constant
12:50of 79, so it's a fixed-width constraint, and it's not really what I want, I don't need
12:56this to be always 79 points in the edge, I just need it to be at least a little gap.
13:02Now the question is, well, what amount? What amount does it have to be from the edge of
13:07the screen, what is it, 20 pixels, 40 pixels, what would it be on a retina display versus a normal display?
13:12Well, I don't really care and luckily I don't have to care.
13:15What I can do is with that constraint selected so that I want this relationship, I want this
13:21space to not just be equal to but either greater than or equal not 79, but I'm going
13:26to click this Standard button, that's an automatic gap between the right-hand side of the view
13:32and the right-hand side of the button that it's in.
13:35So I'm going to go ahead and run this, and it's a little better but still not what I want.
13:42So right now what we're getting is the constraints as it has to be at least the Standard gap
13:46between the right-hand side and edge of the button, that's fine.
13:49But there is also the constraint that says Yes is in the center, and there is also the
13:52constraint that says there must be a gap between the button, so we're still shrinking that button.
13:57So what else can we do?
13:59Well, this is where we can start to play around with the more advanced part of constraints
14:02which is the priority of them. All constraints have priorities.
14:07If I actually select the individual ones, with this Attributes inspector open I can
14:13see they all have this priority, and by default they're all set to 1,000.
14:17So one between the buttons, that's 1,000.
14:21The Center Constraint here has a priority of 1,000, and that means they're all equally
14:26important, and I want to say that's not the case.
14:28Now there is a few ways you might approach this, but if I say, well, really what I want
14:33to describe is I'm saying I want the Yes button to be in the center where possible.
14:38But if it's not possible to be in the center, it's okay that it moves off there.
14:42So what I want to say is that this center priority is actually less important than
14:48the gap between the right-hand side of the disagree button.
14:50So I'm going to highlight this center one and take this priority down a bit, and there
14:57is actually multiple levels you can take it down and Xcode will give you a bit of a hint
15:02as to how this might impact the design.
15:05I'm going to take it down to just priority 470, go ahead and run this again.
15:11Now this is looking a lot better, looks okay in portrait but if we go back to landscape
15:18where there is a bit more room, it's going to move that into the center.
15:22So we haven't gotten rid of that Center Constraint, we've just said it's less important than the other constraints.
15:28And what you'll find is that when you start working with multiple constraints that are
15:31kind of impacting each other, that working with priority is really the best thing to do.
15:36Now sure, okay, I have presented a pretty contrived example here.
15:40I could have laid this out perfectly well by just repositioning these buttons without
15:44having to bother with adding manual constraints, and you'll find you're capable of getting
15:49a great deal of layouts to work without adding manual constraints.
15:52And yes the first time that you need them, you will end up experimenting with different
15:56constraints and priorities to get your custom layout working the way that you wanted.
16:01But unlike a desktop, you don't have to cater for endless amounts of possible window sizes,
16:07it's really just the transition from iPhone 5 to classic iPhone orientation or from portrait
16:13to landscape on iPhones and iPads.
16:16But this is the basics of Autolayout, it often just works immediately in situations that
16:21would have required struts and springs to be manipulated beforehand.
16:26But it's very flexible, and it's configurable in the interface designer, and it allows us
16:30to create interfaces that previously would often require writing code to handle
16:35orientation changes in different screen sizes.
Collapse this transcript
2. iOS Collection Views
Introduction to iOS collection views
00:00Collection views are new in iOS 6, and these are actually my favorite part of iOS 6.
00:05We've had Collection views for Desktop Cocoa development for a while but not in iOS until now.
00:11Though if you've used them in Cocoa, they are not exactly the same as things rarely
00:15carry over exactly from Cocoa. But what are Collection views?
00:20Well, in iOS, we've always had the UI Table view.
00:23This has been the classic data-driven control, whether on iPhone or iPad.
00:28Table views are used in everything, they're in the settings app, they're in the mail application,
00:32they're in the music application, you can have them in your own applications of course.
00:37These can be styled to make them appear with a different look, but it's always a good old UI Table view.
00:42It's always one column wide, it's got multiple rows, but importantly it's a data driven control.
00:49You are not explicitly laying out these rows manually in Xcode, this is dynamic.
00:56You setup the template for these rows, and then you write code so that when your application
01:00runs, you're providing the contents of each item, each individual cell and what's in it,
01:06whether it's a piece of text or a title and a subtitle or a button or an image as well
01:12or several pieces combined.
01:14So these don't go away, we still have Table views.
01:17But with the new iOS Collection views, we have another option
01:21where we're not limited to one column of rows.
01:24So this new Collection view is a data-driven control like Table views but where we have
01:30much more flexibility how to set up these items.
01:33Not just a collection of rows, but we can have rows and columns, we could have a classic grid-based layout.
01:39Well, it wouldn't have to look as formalized as a grid like this, we could use it to set
01:44an interface like this or we could use it to take these items and group them together
01:49and stack, so we could show them in a circle or however you'd want to do them.
01:54Collection views support all this, and it means you can create better layouts.
01:59You could create application like say the Bookstore application on the iPad, either
02:04the Library view of it where we've got multiple grid style rows and columns here,
02:11but perhaps the Bookstore app itself.
02:12Each of these items is dynamic, they weren't setup manually in an interface builder file in Xcode.
02:19Another example would be something like the World Clock app on the iPad.
02:23This is an interface that is built in columns and rows, it doesn't have to be exactly the
02:28same thing for every column. We can choose how these would be represented.
02:33So you might use them to create something like the App Store, you might use them to
02:37create something like the Photos application where you have a very even grid-based layout here.
02:42Although in the Photos application we could choose to view the photos this way, we could
02:46also choose to view them in stacks, and Collection views would support you doing either of these.
02:52Now, these kinds of applications could have been done before Collection views came along,
02:57but it usually required a lot of code.
02:59What we have now is the Collection views provide a framework for building these kinds of screens,
03:05these kinds of layouts. So how do we get started?
03:08Well, know that the Collection view is similar to UI Table view, though it doesn't replace it.
03:13But if you know how to use the Table view, you're after a good start.
03:17And I'm actually going to assume here that you do know at least the basics of working with UI Table views.
03:22That when you've got one, these are controls that themselves, they don't store the data, they just show it.
03:28They need to be connected to a data source class, some code that will provide the data for each element.
03:35For a Table view it's how many rows does this have and what is in each row?
03:40And they're also connected to a delegate class to say what happens when one of the rows is selected.
03:46The data source code and delegate code could be in the same external class, but they don't have to be.
03:51So this is the way Table views work, Collection view is very similar to this.
03:55So some important concept and terms to let us get started.
03:58Our Collection view is not limited to a grid- based layout, but that's certainly the most
04:03common usage of it, so it's the one we'll explore.
04:07So there is this idea of a Collection view, the UICollectionView class, it's the container.
04:12It shows nothing by itself, it expects to contain multiple items.
04:17Now you provide these items by connecting it to a data source like with a Table view.
04:23You have a class that's going to tell this Collection view how many items it has and
04:27what each item is and there are specific methods to supply that.
04:32And these items are whatever you want them to be.
04:34They could represent photos, documents, audio files, or video files, some kind of custom
04:39object or all of the above, whatever that means for your application as long as it can
04:44be given some kind of visual appearance.
04:47And each item is considered a cell, a UICollectionViewCell object.
04:53Again it's your job to provide these cells just as it is to provide the data in a UI Table view.
04:59Now however, with a Table view there is a default layout for a single cell, whereas with
05:05a Collection view, there isn't a default cell. You need to say what this look like, and we'll
05:09see how to do that shortly. So the data source can provide all these cells.
05:13Now these cells, these items, can be exactly the same size, but they don't have to be.
05:18They can be large, small, or a variety.
05:20You might have a dozen, you might have 10,000, and the Collection view will take care
05:25of arranging them, that's what it does.
05:27But because this same Collection view could arrange this in multiple ways--they could
05:32be in stacks, they could be in circles, they could be in the basic grid layout--the Collection
05:37view uses something called a layout object.
05:41These are the rules, this defines the rules for how these items, these cells, are laid out,
05:47how much spacing should be between the items, are there headers and footers to show?
05:52The default provided layout object is what's knows as a flow layout.
05:57This provides all the rules for creating a grid style system of rows and columns.
06:01Well, that doesn't give the full idea of what it's capable of.
06:05As you'll see in a moment, it's very customizable.
06:08But you can even define your own layout objects, your own sets of rules for the Collection view to follow.
06:15So here is the basic idea.
06:16You add a Collection view to your interface, it's the container.
06:21You write some data source code to provide the items, the cells for that Collection view.
06:27And the CollectionViewLayout object says how this should be arranged while it's the Collection
06:32view itself that will actually do the arranging.
06:35And because you want to be able to interact with this, to touch items, to select them,
06:39to scroll up and down or side to side, you'll also provide a delegate object for this Collection
06:45view, and there you write code to respond to those events like selecting something.
06:50So, okay, there can be more to it.
06:52We can split things up into sections, we can talk about having background images and headers
06:58and footers and so on, but this is the core of working with Collection views.
07:02So let's start with this, and we'll add the other things as we go on.
Collapse this transcript
Adding and configuring a UICollectionView
00:00I am going to create a new project and add all of the basic elements of a Collection
00:04view scenario and get them all talking to each other.
00:07This will be simple, but it's going to have all the necessary parts and will get more
00:10complex in the following movies.
00:13So in Xcode, I will create a new iOS application, it will be a single view application.
00:18Now, while Collection views can do more impressive things on the iPad, simply for space issues
00:24I'm going to use the iPhone as it's more visible in a recording like this with a reduced screen size.
00:30So call it CollectionDemo, it will be for the iPhone with storyboards and automatic reference counting.
00:37And I will jump into the main storyboard where I just have the single view controller here.
00:42So right now there's nothing to do with Collection views.
00:45So I am going to come over here into my Object library.
00:49And if down here in the Filter box I will type in the word Collection, you'll see a
00:53few options appear, Collection View Controller, Collection View, View Cell, and Reusable View.
00:59What I want to add is the Collection View itself, I am not adding the Collection View Controller
01:04that would add another view control, another screen, not that that would be bad,
01:09but I just want to add one to this of view controller I already have.
01:13So grab the Collection View, drag it over and try and position it somewhere in the center here.
01:19That will have to do.
01:23And when I drag this on, it's invisible, it doesn't show me anything.
01:27If I expand the dock on the left-hand side, well, I can actually see here that I've really
01:32gotten three things, I have had a Collection View that has been added as well as a Collection View Cell ,
01:38and the Collection View Flow Layout, that's the layout object, the predefined rules
01:44for a grid-based layout in a Collection view.
01:47So it adds this one cell, and if I select that I can see it highlighted over here to about 50x50.
01:54This is not an actual item, a cell is a placeholder, it's a template for an item.
01:58You're going to have to write code to say how many of these there will actually be when the application runs.
02:04As with Table views, cells and collection views are intended to be reusable objects.
02:09So if we have 10,000 pieces of data that might be shown in this application, but only
02:1520 cells can fit on the screen at any one time, we'll actually keep reusing the same cell objects,
02:20just swapping out the data inside them as we scroll up and down.
02:24And just so we'll be able to make this visible, I am going to go into my Inspectors here,
02:29making sure I have the cell selected.
02:33I am going to change its background to a light gray color.
02:36And again, making sure it's the cell that's selected, I am going to come here to the Reuse Identifier section.
02:43This is the same as having a Reuse Identifier for a table view.
02:48I'll type in demoCell, it doesn't really matter what you call it as long as its name you remember.
02:53The idea here is that you might have multiple cell templates, you might have different cells
02:58for say book products and other ones for album products and other ones for software products,
03:04so you may have several different configurations, and you can give them all their own unique
03:08name so that you can reuse different ones later and get the right one at the right time.
03:13But for right now all I need to do is have some identifier string in here of my own choosing.
03:19Now if I just go ahead and run this, I have all the necessary actual UI pieces, but it's
03:25not going to do anything at all because we're not providing the necessary data source.
03:31We don't see anything, not even that one cell that was in the design.
03:35That's because we're not providing the necessary data source, we are not saying
03:41does this have any data in it, does it have any cells, does it have any items?
03:45The collection view needs to be hooked up to an object to provide this information.
03:49If I select the Collection View in my dock here-- and I am going to go over to the Connections inspector--
03:54I see two outlets here for dataSource and delegate.
03:59The most important one right now is dataSource, but I am going to hook both of these up.
04:03Now this is virtually identical to working with the Table View Controller in previous versions of iOS.
04:09I need to connect these outlets to a class. Now I could create a new class and connect it
04:13to that, but for this demo I am just going to tell the Collection view to look for this
04:17code in the current view controller.
04:18So I am going to drag over the dataSource, click and drag over to View Controller and
04:24let go and do the same with the delegate, click and drag over to View Controller and let go.
04:30What that means is this Collection View object is now going to look into the View Controller
04:35implementation code to find the information about how many cells do I have and what's in each cells.
04:40It's going to look for specific methods, and I'll be writing the code in these files.
04:46Well, the first thing that I need to do-- I don't have to do it, but it's good practice--
04:51is to jump into the view Controller header file and say that I'm going to support those
04:55delicate protocols, I am going to be both a dataSource and a delegate for that collection view.
05:01So let's start typing in UICollectionViewDataSource, and it appears, hit Enter comma UICollectionViewDelegate.
05:12By doing that, if I was to go ahead and build this project, what I'd get is a few warnings
05:16here of the incomplete implementation.
05:19I haven't supported the methods that I said I was going to.
05:23There are actually three warnings here saying you haven't provided the numberOfItemsInSection
05:28for the Collection view, and you also haven't provided the collectionView:cellForItemAtIndexPath.
05:35Again if you're familiar with working with Table views, you'll see that these are very
05:39similar methods to what we are used to.
05:42Okay, so I can do that now, I'm in my implementation file, I'll just type the dash and collectionView,
05:49I am looking for a numberOfItemsInSection, there it is.
05:53There's a quite a few methods here, so it might take you a second to find the right one.
05:59It's also now complaining I need to support collectionView:cellForItemAtIndexPath so I'll
06:05do that as well -collectionView, there we go, it's the second one from the top for me,
06:13cellForItemAtIndexPath.
06:17So I have these method signatures now, but I need to say what they actually do.
06:21This first one for collectionView: numberOfItemsInSection needs to return an NSInteger.
06:28It's simply saying how many items do I have?
06:31Like a table view, a collection view can be split into multiple sections to group
06:36some of these items together.
06:37I didn't do that, so I just have one section, and that's actually the default, I don't have
06:42to say I have one section.
06:44If I don't say anything, it's assumed I have one section.
06:47For the purposes of this demo I am just going to say return 15, I'm going to say I have 15 items.
06:52Well, next, I have to describe them all.
06:57This method will be called automatically once for that section, it will say you have 15 items.
07:02What will then happen is this method gets called 15 times.
07:07Passing in an index path and asking what's at position one, what's at position two, what's at position three?
07:13And this is the more important, more involved method, this is where we have to return the
07:19actual cell, you can see the return type is a UICollectionViewCell.
07:24Now as I mentioned earlier what we do here is like what we do with table views.
07:28Before just creating a new cell object, we can ask the Collection view if it has any
07:34cells it's not showing, is there anything we can reuse?
07:43So I will create a new pointer for a UICollectionViewCell object, and instead of saying alloc and init
07:50I am going to talk to the collectionView parameter that was passed in and call its method,
07:57dequeueReusableCellWithReuseIdentifier,
07:59again, very similar to working with a table view.
08:01We are asking do you have any reusable cells? Do you have any cells you're not using right
08:06now that we should use instead of instantiating a new object?
08:10Now, what I have to do is pass it a string, that identifier.
08:14If you remember in the storyboard I called it demoCell.
08:18Now I also have an index path, and that parameter is just passed into this method so I'll just reuse that.
08:23I'm not actually going to create different items for each of these, I am just going to
08:28pass back 15 of the same item, but we do have that index path parameter so that we could
08:34change and write more substantial code here to create different kinds of objects and pass them back.
08:40Now if you are familiar with table views, you're probably looking at this going, okay,
08:43it's pretty much the same thing, and what you'd think I'm about to do next is write
08:48a little bit of code like this...
08:53Basically asking is there a cell? Do I have an object? I asked the Collection View to
08:59dequeue any reusable cell, but it might not have had a reusable cell, in which case this
09:04would be nil, and I would have to instantiate one. Well, not anymore.
09:09The way that this method works now is it's going to guarantee that you will get an instantiated object back.
09:15It's going to look for a reusable cell, if there is one, you'll get that back.
09:19If there isn't one, it will instantiate one based on whatever the identifier of that cell was
09:24and what that's connected to.
09:26In this case, it's from our little default gray box that's in the storyboard.
09:30We'll make a more complex one later.
09:32Now when I create a more complex one, if I had that cell defined and say a separate class
09:37and not in the storyboard, that's completely fine too.
09:40I would add one line to register that custom class with the Collection view so that this
09:45same call to dequeue a reusable cell would know where to find it.
09:49Now when we make a more complex cell we might have labels and buttons and images inside it to configure.
09:54Currently this object is really just a plain gray box. I am just going to return it.
09:59I am going to save that and run it, and it runs, we have 15 items showing up.
10:06I could change the orientation, and it will alter it, and if you notice the layout is
10:10We can get an even layout, here three rows of five, and here we have to have one row of eight,
10:16one row or seven, and the Collection View is doing that based on the rules that are
10:20defined in the Collection View layout object, the flow layout.
10:24Let's take it a little further, I am going to stop this go back in and change this and
10:28say I'd rather have 150 objects, and this is just to show its very simple is going to
10:33instantiate a 150 of the same things, but the collection view itself not only shows them,
10:39but it will let us scroll up and down and handle those object being reused in the background.
10:45Once again, switching to landscape, I can scroll up and down as well.
10:49Now while of the collection view is what's handling the arrangements of these, it's the
10:57layout control, the flow layout, that is actually saying things like how much spacing does
11:02there have to be in between these different items?
11:05And if I stop this and go back into the storyboard, I can actually select that Collection View Flow Layout object.
11:11it isn't visible here on the View Controller, but it is a full-fledged object.
11:16If I open up my inspector, I will find a few things I can change about it.
11:21One for example is working with the minimum spacing for cells and for lines, we'll get
11:25a bit more into this later, but if I start to say manipulate it, say 20 for cells
11:34and 30 for lines, go ahead and run this.
11:39You start to see a slightly different impact here.
11:44Now what you'll find it's very telling that the phrase that they use here is Minimum Spacing, not exact spacing.
11:51Because what it's going to do based on its own rules is lay them out, it's always going
11:55to be at least 20, but it might be a little more if it thinks that's a better layout.
12:00Another option we have here are Section Insets.
12:05What that will actually do is create it's like a padding all the way around the content.
12:09So if I wanted to have multiple options but to have some blank space around the edges
12:14of this collection view I could do this in.
12:17If you actually watch the gray box as I am increasing this value, you see it move in
12:21from the left or move down from the top.
12:26I'll nudge them up on the bottom of the right, and I'll do one more thing before we go back
12:31in which is switching over here to the attribute inspector.
12:34The only option that I have here is for scroll direction, this is the flow layout,
12:39I can change them from vertical to horizontal, run it again.
12:44Now we've got much more spacing going on, we've got some blank area around the outsides
12:48as well, and I don't scroll up and down, I can scroll left to right.
12:55Same if we switch into landscape, we're scrolling left to right now, but very easy to do,
13:00very easy to start configuring.
13:01We've got a bit more that we are going to have to work on if we start to get irregular
13:06items here, if they are of different sizes.
13:09And sure, there is more to do, we can have custom cells, we can split this up into sections,
13:13we can respond to selection.
13:15But this is how we'd get started, to load the collection view up with a bunch of items
13:20and let it take of arranging them, of scrolling them, of reusing the graphical objects that display them.
13:26So next up, we are going to start making a more complex cell.
Collapse this transcript
Defining a UICollectionViewCell
00:00When you work with UI Table views, there is a basic default layout provided for a table
00:05view cell with a place for a Title and a couple of different styles.
00:09You can start loading it up with your data. You can customize it a bit.
00:13You can choose to use subtitles or put an image on the left and a disclosure button
00:17on the right, but it's very easy to get that standard iOS look and feel for a Table view.
00:23But this isn't true with collection views.
00:25The default cell for a collection view does not have any predefined labels or buttons or anything.
00:30It is a totally blank canvas because there simply isn't a default look
00:35and feel for a Collection view. Now canvas is actually a good name for this.
00:39It does know how to draw itself, and we could easily give it a color, but there's nothing on it.
00:44So, you will always need to customize it and your own user interface elements and typically
00:49provide your own custom class for outlets and actions and any behavior that you need.
00:54Now, CollectionViewCell is a visual element so while you could create this cell all in
00:59code, more typically, you'll arrange the visual parts in Interface Builder in Xcode.
01:04You can either do it in a Storyboard or you could put it in a separate NIB file.
01:08You get the same abilities in both places, it just depends on how you like to manage your project.
01:13So, I'm jumping over here into a project in Xcode.
01:17This is where I finished off from the previous one, although I've taken it back down to
01:21a standard vertical flow and just 15 elements.
01:25If I had to run it, we can see that by giving these cells a background, we can see them
01:30appear, but we're going to have to customize them to make them do anything useful.
01:34Now, when I dragged on that Collection view, and I can see this over here in the dock,
01:40I did get that one Collection View Cell, the blank canvas.
01:44This is based on the default UICollectionViewCell class.
01:47I could see that by selecting it and then going over into my Identity Inspector.
01:52So this is what I'm going to start with, but first I'm going to add a new class to put
01:56any outlets or actions that I need. So, I'm going to add a new file in Xcode.
02:05It's going to be an iOS Objective-C class.
02:08I'm going to call it ProductCell because I'm going to show kinds of products like DVDs
02:12and Blu-Ray and applications.
02:15And importantly, I need to make sure that I'm inheriting from the correct superclass.
02:20So, this is a subclass of UICollectionViewCell. It adds the .h and the .m files to my project.
02:30Now importantly, what I'm going to do here is jump back into the Storyboard now, select
02:35that cell and in the Identity Inspector, the third one, I'm going to make sure that
02:39I'm connected to my new one. It might not show up.
02:41So, I'm just going to type it in here.
02:46This is just to make the link between the element on the Storyboard and the actual new
02:50code file that I just created.
02:52Next, I'm going to go into my Object Library and find just a simple label.
02:59Drag that into the cell itself, and I'm just going to arrange it here in the center.
03:07I'm double-checking here that the label is inside the Product Cell here, which is where I'd want it.
03:13I don't want it anywhere else on the interface.
03:15Now, I want to connect this label to our new custom class so that we can get to it when
03:20we are configuring these cell objects.
03:22So, I'm going to switch into a System view just to give myself a bit more room here.
03:29Now, because I'm currently in the Storyboard that is connected to the larger view controller,
03:35it'll certainly show me the ViewController class here, the ViewController header file,
03:39and it's not what I want. I want my new custom class.
03:42So, I'm going to need to manually change it by clicking the Automatic part, switch to
03:46Manual and drop into my Collection project. I'm looking for the ProductCell header file.
03:53Now, what I can do is Ctrl-drag, so hold down the Ctrl key, drag from Label over into the
03:59interface section to insert the outlet.
04:01It should be of type UILabel, and I'll just call it cellTitle.
04:06Now, I can switch back out of the System mode.
04:10Now very importantly, I'm just going to double- check that on this cell, the actual cell itself
04:15that we do still have the Reuse Identifier we were using before, demoCell, and that's
04:20the name we're going to be using when we're creating it in code.
04:23Back into the main ViewController class in our implementation here, I'm going to come
04:28down to the collectionView: cellForItemAtIndexPath.
04:33This is the code that actually creates and configures that cell and returns it.
04:38Now here's where we can finally do a bit of customization.
04:41Instead of creating a generic UICollectionViewCell, I can now create a new instance of that ProductCell
04:47that I have and get to its title.
04:50Well, the first thing I'm going to need to do is to make sure I've got an import for that.
04:58And then in my code, I'll change it here. Now let's just test it.
05:05If this is an instance of the ProductCell, I should be able to get to cellTitle.text.
05:14Let's just put the word test in here, make sure that's in a string literal, save that and run it.
05:24Looks good. We are now actually talking directly to that object and setting properties inside it.
05:29Now, it's a little boring just to have test there all the time.
05:34Usually, what I'd be doing is having a collection of model objects to start to configure the
05:38data in my cells, for here let's just have some random product names.
05:43I'll create a simple array of productNames here like CD, DVD, Blu-Ray, Book, App, and
05:48I'm just going to randomly select one of these.
05:55And it should give me a generically random number between 0 and 4, and I'll now use that
06:02to get into the productNames array.
06:06All right, so we're getting some more random data in there, and as you can see,
06:12some of the changes in the text that I have are kind of blurring out some of design here.
06:16Blu-Ray doesn't look too good at all.
06:18Currently, the layout object is assuming all these cells are exactly the same size and the same layout.
06:24We could change that in the Layout object itself, or we could dynamically change it in code, but that's another topic.
Collapse this transcript
Adding highlighting and selection to view cells
00:00Once we've started to create custom cells, it's a common question to want to know how
00:04do we start to interact with these, how can we touch one to select it, and so on.
00:08Well, that support thankfully is already built into collection view.
00:12As well as responding to scrolling when you have more than one screen's worth of items,
00:17every time we tap an item, it is already going looking for a delegate to respond to that event.
00:23So, I'm going to jump back into the code here.
00:25Now, if I look at my MainStoryboard and highlight the Collection View, and it's going to be
00:29easier to select it from the dock or the jump bar rather than on the actual View Controller
00:35itself just because it's not really visible.
00:37I'll open up the Inspector, and I'll see my in Connections Inspector that I am hooking
00:42up my delegate over to my View Controller.
00:45You could hook it up to any object that you wanted to.
00:47This is just most convenient for me.
00:49So, it's in the View Controller code file that I'll need to write the delegate code to respond to this.
00:55It doesn't really matter where I put it, I'm just going to put it in here after the opening
01:00implementation and the method that I'm looking for is collectionView didSelectItemAtIndexPath.
01:06Now, one of the things you have to be careful of here is there are some similarly named methods.
01:13There is a didDeselectItemAtIndexPath which can look very much identical when you're just
01:19scanning them correctly, but what I'm looking for is this one, collectionView didSelectItemAtIndexPath.
01:27This will be called when we tap on one of those items, it will pass in an indexPath
01:32parameter which will give us both an integer for the section and an integer for the row.
01:37We only have one section right now, but I'll do a little NSLog message to write out both pieces of information.
01:47So just using indexPath.row for the item and indexPath.section which right now should be
01:52zero all the time, let's test this. I see behind the scenes here.
01:59I'll just open up my messages that are coming out, Item 6 in section 0, Item 0, Item 14, and so on.
02:08So we're responding to these events already.
02:11Although the actual user interface doesn't give us that clue, it's only by looking
02:15at that message, we could tell that's what's happening.
02:17Often, you want to change the visual appearance of the cell when it's tapped, not always.
02:22Sometimes, you might just immediately transition to another View Controller or pop up a modal
02:27window, but it's common to give the cell a different look when someone's finger is touching it.
02:32Now here's the thing, there is actually a lot more going on here than you can see.
02:36As far as the Collection View is concerned, it's already tracking multiple states for
02:41all of these items, even if it doesn't look like it.
02:44And there's not just two states, is someone touching it or are they not touching it,
02:48there's actually three states.
02:50The cell can be normal, as we're seeing most of them here,
02:53it can be in a highlighted state, or it can be in a selected state, and all of this is
02:59built into Collection View, and it's happening already.
03:01So, what's the difference?
03:02Well, highlighted means while your finger is actually touching the cell, there is a
03:07Boolean property called highlighted in every cell object that's automatically set to yes
03:12when I would touch something, and it's set off to no when I let go.
03:17Now, selected on the other hand is that you touch and release one cell, and that cell
03:22will have a Bool property called selected set to yes. When you touch another item, the
03:27first one selected becomes no and the second one selected is yes.
03:31But you say it doesn't look any different. Well, no.
03:34Making it look different is our job.
03:37So these states are being tracked, but we need to do some kind of visual appearance work.
03:42That's completely up to us.
03:44So, first let's handle the idea of selection, and I'm going to handle selection because
03:49we've already got part of that code written.
03:51Here, where we handle the didSelectItemAtIndexPath, what I can do is change the color of the items.
03:59First, what I need to do is grab a reference to the currently selected cell which I'm going
04:05to do by calling the cellForItemAtIndexPath of the collectionView object.
04:10Then I'm simply going to reach into its built-in property called contentView, into the backgroundColor
04:15of that and set that to the very basic UIColor, blueColor. Let's test that.
04:22So, I come over, I tap something, it becomes selected.
04:27I come over, I tap another, well, it becomes selected.
04:31The first one is technically deselected, but there's no code there to change the color back.
04:36But you can at least start to see how we can start to interact with this stuff.
04:41So a little bit more of a tweak needed first. Just as we have the Collection view didSelectItemAtIndexPath,
04:48we also have the Collection view didDeselectItemAtIndexPath method
04:53where what I could do here is just change the color back.
04:59Now I'll grab the code that I just used, paste it in there, and change that back instead to the lightGrayColor.
05:11Test that again. We click on one, it's considered selected.
05:16We click on another, that one turns back, this one is now selected.
05:24It is very careful and conscious of the bounds of these.
05:27If I tap somewhere in between, it doesn't count as anything else being selected.
05:31So, back into the code, now what you'll find is highlighting is very similar.
05:36So, if you wanted to use another state or another visual appearance when somebody was
05:41actually touching that item, at the moment they were touching that cell, we could do it that way as well.
05:47You will find there is a collectionViewdidHighlightItemAtIndexPath as well as a collectionView did UnhighlightItemAtIndexPath.
05:55And we could use these.
05:57That's the one way to do it, but I'm going to show you another way in just a moment that
06:01will let us not only leave this code out, but to let us get rid of most of this code as well up here.
06:07Now it's good to see the fact that we have these very explicit delegate events about
06:12selecting an item and deselecting an item and the Collection View by default handles single state selection.
06:20It only has one of the items has its internal selected Bool set to true at anyone time.
06:26You can actually change that, but that is the default that's the most common way to do it.
06:30But rather than write all this manual code to change the background color, there is a
06:34way to automatically have the visual state of a cell change for highlighting and selection,
06:40but it does mean we have to understand a little bit more about how the collection view cell is constructed.
Collapse this transcript
Using background views
00:00The UICollectionViewCell, this is where you're going to be adding your user interface elements,
00:05labels, image views, whatever you need.
00:07And when you drag on elements, what you're actually adding them to is an inner part of
00:12this collection view cell, it's something called the contentView, and this is just a
00:16UI view, it's a container for other elements.
00:19But the default background of the content view area is transparent. That's why one of
00:23the early things I did with it was set the background color just so we could actually
00:28see this cell over the black background of the collection view, otherwise it would have
00:32been a black label on a transparent background on a black background, we wouldn't have been
00:36able to see anything, so we have this contentView.
00:39But there are a couple of other views already built into this UICollectionViewCell, we haven't used them yet.
00:46We also have a backgroundView property and a selectedBackgroundView property.
00:51Now both of these are nil, they're empty by default, but the benefit of using them is
00:56if you put stuff in these views, you decide to use an image or set a color in the background,
01:02well, then the Collection view will automatically swap them in and out as it's tracking the
01:07highlighted and selected state of each shell. We don't have to write any code to respond to those events.
01:13However, there is one slight problem. If I have defined the backgroundView color and
01:17the selectedBackgroundView color as well as the contentView backgroundColor, the contentView
01:22will always win, because this has to be on top, it's the thing that contains your actual
01:28user interface elements, so select your background view and background view behind and even
01:33if the Collection View is swapping them out, we're not going to be able to see them, because
01:38they're behind that solid background view color.
01:40So one of the things I will have to do is remove the background color of the contentView
01:45so we can see the effect of that. So let's take a look.
01:48So back into Xcode, if I take a look at this cell that I have here and open up the Attributes
01:54Inspector for it, I can see that I have got the background of a light gray color, this
01:58is what I set a little earlier.
02:00If I take it back to the default of no background color, and we go ahead and run this,
02:07well, it's not a terrifically impressive application.
02:09Everything is actually there, we just got a black label on a transparent background
02:14with black in the back, so we're not seeing anything.
02:16Well, let's fix that.
02:18I want to set both the backgroundView and the selectedBackgroundView.
02:21Now you might think a good place to do this would be in the view controller in the cellForItemAtIndexPath method.
02:27After all, that's where we were setting the label on that cell, so maybe we should set
02:32the background and selectedBackgroundView here too.
02:35Well, no, not really, that's not the best place. After all, this cell could be being
02:40reused hundreds or thousands of times.
02:42The better place to put this in is actually when the cell is instantiated, and that is
02:46our ProductCell object. We haven't really been using this for much so far just as a place
02:52to have the outlets for that label, but I'm going to jump into the implementation.
02:56Now when I created this, I did get the default skeleton code here, and it provided me an
03:03initWithFrame method, that's not going to work for us, because we're going to be initializing
03:09this, and it's going to be brought out of the storyboard, and when something is initialized
03:13out of a XIB file or storyboard, let's using init with coder instead.
03:17I could type that in, but I'm going to find one over here in my code snippets, which you
03:21should find one there too, jump into the Code Snippet Library, I'll just filter down
03:27at the bottom here on init, and I'm looking for initWithCoder, there we go, that's the one
03:32I want, drag that after initWithFrame, and we get initWithCoder.
03:39The standard outline here is just calling initWithCoder or the super class, and here
03:43is where we can put in a little bit of code to create those backgroundView and create the background color.
03:50Here's the issue, that I do have self.backgroundView as a property and is also selected backgroundView
03:57as a property, they're both nil right now.
03:59So I have to actually instantiate a UI view object, I'm going to just paste in a little
04:04code to do this, rather than have you watch me type this.
04:08So in line 26, I am instantiating a UIView called bg, just allocating it and knitting
04:14with the frame that's 50x50. It doesn't really matter what size I make it because
04:19it's the layout object that's going to be responsible for creating the size of it on
04:24the screen screen, but this will do.
04:26Then on the next line, I'm going to set it to the backgroundView property of self, and
04:31then I can reach into it and set the background color of the UIView to in this case white.
04:37So that would be the standard color for the backgroundView property.
04:40Then I'm going to repeat the whole thing, just instantiating another UIView object and setting
04:44its background color to dark gray, go ahead and run this.
04:50Now I have got the white background the default background color, when I touch, that will
04:54be considered highlighted, it will swap that state out for a highlight as well as a selected,
05:00so when I let go, we're still getting the blue here, and that's just because I still
05:04have the code running in the view controller, so let's get rid of that.
05:10Jump over into ViewController, and up here is where I have two methods for didSelectItemAtIndexPath,
05:21it's grabbing that cell and setting its background color, and then didDeselectItemAtIndexPath.
05:24I don't need either of these, I can just get rid of them.
05:31Now we have no code whatsoever that's handling the select and the highlight, but it is still
05:37working from the fact that we just set those background views.
05:41So highlight goes gray, but so does a select. If I select something else, that select turns off,
05:45and that's all handled by the collection view itself, it's working without code.
05:53If you need a different behavior, you need the highlight and selected states to be different
05:58from each or you need multiple selections to be supported, then you're going to have
06:02to get a bit more into the code, but if you want this basic default behavior of being
06:08able to just change the states by setting them up up front, then all you need to do is
06:12set the backgroundView and selectedBackgroundView objects in your custom cell.
Collapse this transcript
Splitting a collection view into sections
00:00As with table views, collection views can also be split up into sections, grouping your
00:04items together, and these sections can have their own headers and footers.
00:08We'll see that in a moment. First, let's just see how to do it.
00:11So I have here a new Collection View project that I have created and just done a little bit of groundwork.
00:17For our purposes here, what I'd like this to do is show a collection of short words,
00:22twoLetterWords and threeLetterWords and fourLetterWords, maybe I'm a Scrabble fan.
00:26So, I have got a little bit of this working so far, it's creating some two letter word items here.
00:31If I jump back in and explain what I've got, I've already added the Collection View to
00:36the View Controller, inside that I have the regular cell that I've hooked up to our custom
00:42class with one label on it, all the stuff that we've done already, I just needed to
00:47have a bit more complex data that we could group together into sections.
00:51So what I have done instead of loading in a file or connecting to core data for our
00:55purposes of simplicity, in my ViewController I'm defining three NSArrays, and I'm using
01:01the new NSArray literal format just to load them up with some pretty simple data.
01:06The problem is is by default the Collection View thinks it only has one section, so I
01:11might've written a whole bunch of other code to load stuff in, but if it thinks it only
01:15has one section, it's never going to ask for anything else.
01:19So before I do anything else, I'm going to add the method numberOfSectionsInCollectionView,
01:27that's the one, I don't really have to be dynamic here because I know I have three
01:31arrays, so I'm just going to return the number 3.
01:35Then as I go down a little further, nothing particularly remarkable happening here.
01:39When we jump into the number of items in section, this was the place that previously I was just
01:43returning the flat number 15 or 150.
01:47What I'm doing is just a simple switch statement that's going to either return the count of
01:52the two letter word array, the count of the three letter word array, or the count of the four letter word array.
01:56Very similarly down here in the standard cellForItemAtIndexPath, instead of just creating that cell
02:04asking if there is a reusable one available and setting some random text, I'm going to do this similar
02:10switch statement here that's going to access the right part of each of these arrays, nothing
02:15remarkable here, in fact nothing really different about anything that we've seen so far.
02:19I'm going to go ahead and run this.
02:22Now what's happening is it is splitting our items up into different sections, it's not
02:27collapsing them all together, we can see there is a division between them.
02:31That division is completely configurable.
02:34We can start to work with the spacing, we can add headers and footers.
02:38But one of the first things we're running into is an issue that given the four letter
02:42words aren't all fitting well in the cells.
02:45Now I could change the layout object to make all the cells bigger, but I really don't want to do that.
02:51So up next, let's see how to dynamically change the size of the cells as they're been created
02:57so that some are larger and some are smaller.
Collapse this transcript
Dynamically changing the size of view cells
00:00It's an important point to understand with Collection views that it isn't the cells themselves
00:05that control how big they should be in the Collection View, it's the layout object.
00:10That's what controls the size of all of these cells.
00:13Now if I jump back into my storyboard here and expand the Collection View, I can find
00:18that Layout object inside the Collection View.
00:21This is what controls the size of all these cells.
00:24If I jump over to my Size Inspector, I'm going to see here that currently they are 50x50,
00:29and that will apply to all of them.
00:31Any change that I make here will also apply to all of them.
00:35So what if I want to have a bit more dynamic behavior, what can I do?
00:39Well, it's still the Flow Layout object that's going to control that, but I can't change
00:44anything here to just make things auto expand and auto contract.
00:48What's the solution here is all about delegation, like so many things in iOS.
00:53Now we're already behaving as a delegate.
00:56If I highlight the Collection View itself and go to my Connections Inspector, this is
01:00where I'm volunteering to be the delegate here for the dataSource and the normal delegate
01:05to respond to selections to highlighting and deselecting things.
01:10But I can also be the delegate for the Flow Layout.
01:13Now the way that I do this is go over into my ViewController here.
01:16This is where I'm currently saying I'm supporting the UICollectionViewDataSource and UICollectionViewDelegate,
01:21and before this closing bracket, I'm going to put in a comma and also the UICollectionViewDelegateFlowLayout.
01:29So, responding to the events in the FlowLayout object as well as the regular Collection View.
01:37Save that and jump over into the implementation file.
01:40Here we can write just a little bit of extra code to control the sizing independently for each cell.
01:47The method that we want here is the collectionViewSizeForItemAtIndexPath.
01:53Let's see if I can find this one here. There we go, that's it.
01:56Sometimes a little bit tough to see, if you're actually looking at the big dropdown window,
02:01but if you look up here where I'm actually typing, I can see the little gray text that
02:06says that's what I'm looking for here, collectionView:layout:sizeForItemAtIndexPath.
02:13This returns CGSize that basically just has the height and the width of each individual
02:19cell, because it's accepting a parameter and index path that will be passed in,
02:24so this will be called repeatedly for every item in every section.
02:28So I get that both the section and a row, and I could write lots of code to ask what
02:32individuals cell this is going to be. What I'm going to do is just do something fairly
02:36generic and just say all the items in the final section should be bigger.
02:42So we have three sections, 0, 1, and 2, so I'll ask if indexPath.Section = 2 and will just return
02:49a CGSizeMake of a couple of floats. If that is that last one I'm going to start with
02:5480 wide using the .f, so it'll take it as a float and 50 high.
03:02However, seeing as I do always have to return a CGSize, I better have an else as well,
03:08so if it's not in the last section, we'll just return the standard 50x50 size. Save that and run it.
03:20Then we see that do have dynamically sizing cells, the first two sections of the standard
03:24square are 50x50 and the last section is 80x50.
03:28However, I'm still running into a problem in that I'm not getting all of those words,
03:33I'm still getting the dot, dot, dot, the ellipses here.
03:36So what's the problem?
03:37Well, now what we're running into is almost certainly a problem with the Label and with
03:41the constraints inside the individual cells, so let's go back and take a look at that.
03:46I am going to stop this and jump into the storyboard.
03:50Selecting this cell itself--and I've called it wordCell here--I can expand that, I find
03:54I have a Label inside it.
03:57And the Label itself has two constraints, I can expand the right-hand side just to see these a little better.
04:04I have a Height constraint and a Width constraint.
04:07And the Width constraint is Equal, not Equal to or Greater Than, but Equal, so what it's
04:13saying is this Label is always going to be equal to 42, that fits quite nicely inside 50,
04:19but if it's still 42 inside 80, it's not actually growing.
04:23Now, there's a couple of ways I could try and fix this.
04:26One is I could change this to Greater Than or Equal to, and that's almost certainly not going to work.
04:30In fact, look over here that I currently have two in the dock, a Height
04:34of 21 that's fixed, and a Width of 42 that's fixed.
04:37If I try and make that Greater Than or Equal, it's actually dumping in another one, and
04:42you'll occasionally see this where there's some kind of conflicts in the a tight space, that
04:47what it's actually doing is taking that fixed Width of 42 as being really important because
04:52as the priority of 1,000, and it's not letting me reassign this, so it's actually
04:58adding another one, that's not what I want.
05:00So what I'm first going to do, I'll delete that new constraint that was created, go back
05:04to the Width of 42, that's fixed, I'm just going to ramp down the priority of this and
05:09just say it's just really not that important.
05:12I might have to do a little bit of experimenting with this.
05:14I've taken this down to about 235. Now I'll go ahead and run this again.
05:19That's a lot better.
05:21Now we're actually saying that the Label is allowed to resize itself if that's important,
05:26if you have got bigger contents inside it.
05:29And this is how we'd start to manipulate our cells on the fly.
05:33Of course, we can have multiple cell types.
05:36We could create new cells and new classes for those cells.
05:39So if you do have things that are substantially different, you're probably actually going
05:42to create an entirely new cell, with a different class and a different ID, but you can do some
05:48at least small rearranging of the cells that you do have in response to the data you have.
05:53And that's an important distinction.
05:55If you ever use this actual method, I'll jump back into it over here.
06:01So if you use this sizeForItemAtIndexPath method, know that the cell has not actually been created yet.
06:09It's asking for the size of it so that it can create it. What that means is I cannot
06:13get to the cell object or get to it properties here.
06:16I have to make all my decisions based on the actual data that's going to be put into the
06:21cell, not on the cell itself, because this method sizeForItemAtIndexPath will be called
06:28before this method, the cellForItemAtIndexPath.
06:31So, all your decisions about size need to be made on the data itself, not on the properties of the cell.
06:40So this is starting to get a bit more useful.
06:42Next, let's see how to add headers and footers to this.
Collapse this transcript
Adding headers and footers to a collection view
00:00Adding headers and footers to a Collection view is based on a new kind of object,
00:05something called a Supplementary Reusable view. This sounds like a mouthful, but it really isn't.
00:10Supplementary view is simply to distinguish it from our regular view cells or actual data.
00:15So if we want to add a header or add a footer to our sections, well, that isn't our important
00:21data, it is extra, it is supplementary and reusable, because just like our reusable view
00:26cells, if we are splitting our data into multiple sections, we would like to reuse those supplementary
00:32header and footer objects if we can.
00:34The assumption is your headers are going to be dynamic, they're going to have say labels
00:39on them that can change, they are data-driven just like your cells, but just nowhere near as complex.
00:44So how do we add one?
00:45Well, I am beginning where we finished off last time, and I have this basic application
00:50with several cells just split into three different sections, and I want to add headers and/or footers to this.
00:56So I am going to jump into the Storyboard for this application.
00:59Now if you have looked at the Object library, when we've been adding some of these collection
01:05view objects, I am just going to filter on collection in the Object library.
01:10I actually find that there is something called a Collection Reusable View, and this is
01:16what is used for headers or footers, but we don't need to drag it onto the storyboard because
01:21if we are actually adding it on the storyboard, there is an easier way.
01:25If I go over into my dock of the storyboard here, find the Collection View itself, expand
01:32that so I can see it a little better and jump over to my Attributes Inspector, again I want
01:36to make sure I am selecting the Collection View object.
01:39What I should get then is these two check boxes in the accessory section, one for section
01:44header and one for section footer, selecting either of these will add a Supplementary Reusable View to the Collection view.
01:52You can of course add it to a different XIB file if you want to, but for our purposes this is fine.
01:57In fact, when I click this, you'll see it add some extra space at the top here, add a header, add a footer.
02:04We can't actually see them here because I have still got white on white going on--
02:08or really, it's transparent with a white background.
02:11But over here in the dock I see that I have one Collection Reusable View and clicking
02:15that will highlight it in the Storyboard view, same for the footer, because like the cell
02:20on the Collection view itself these are all transparent. There is nothing on them until you put it on.
02:25So you get used to selecting them on the dock itself or in the jump bar. Okay, now what?
02:31Well, what am I actually going to do is get rid of my footer here, I am just going
02:34to go through the process of adding a header because it's exactly the same as a footer,
02:38and this will just half the time than it needs to take.
02:42So selecting this header, so I can see it's just showing up highlighted here.
02:47The size of the header like the size of all of our view cells is not actually controlled
02:51by the header itself, it's controlled by the Flow Layout object.
02:55If I were to select that and go over into size, you will see that not only now that
02:59we have the cell size of 50x50, but we have a header size of 50x50.
03:03That really is a minimum height, but it means it's 50 high.
03:08That's okay for us to get started with. We may want to experiment with that later.
03:12What I am going to do so it's visible is select that Reusable view, and I am going to give
03:17it just a background color so we can see it. I will just make it a light gray color.
03:22And just to prove a point, if I go ahead and run this, I am not going to see anything,
03:26I'll get the spacing, but I won't actually see the object because there's nothing that's
03:30going to instantiate it probably.
03:32What I wanted to something a bit more involved. Quite typically with a header, you're going
03:35to want some data on it, perhaps a label with a category heading.
03:40So in my Object Library, I'm going to select a label, drag it into the header,
03:47and just double-checking in the dock that it is inside my Collection Reusable view.
03:51I will just drag this a little wider, so it gives us a little space, center-align it,
03:58and I will make it bold.
03:59But if I want to get to this through code, well, it's like getting to the label inside the cell.
04:04I can't expect that the default built-in class has support for this new thing that I
04:09just added, so I am going to have to make my own class.
04:11So I am going to add a new class to this project.
04:16Cocoa Touch Objective-C class of course, to class that represents my header for this Word
04:21app, so I will cal lit Word header, and this is the class that it needs to be a subclass
04:27of is UICollectionReusableView.
04:32We want to be very careful here not to create it as a subclass of UICollectionViewCell.
04:35So UICollectionReusableView, click Next, click Create.
04:40Really, right now the only reason I'm doing this is to have a place to put an outlet for that label.
04:44So the class is created, but right now there is no connection between that class, and this
04:50actual reusable view element.
04:52I am going to select that over here in the dock, because if we jump over to the identity
04:57inspector we can see that right now it's just hooked up to the standard default UICollectionReusableView,
05:03I need to change that to my one which was WordHeader.
05:09So it now at least knows it's associated with that code file.
05:13However, I still need to explicitly connect the label to the code.
05:18So giving myself a bit more room, I'm going to jump into Assistant view.
05:22As we saw before what will typically happen with assistant view is you will get the Automatic
05:26option show up where it's going to connect you to the view Controller, what you actually
05:30need is the manual option, so it will connect to the new word header class.
05:35And as long as the header has been associated with this class, I should be able to select
05:40that label and either from the storyboard itself or from the dock, Ctrl-drag into the interface.
05:47Let go and insert an outlet, I'll call this headerTitle.
05:54I'll jump back into the regular editor here.
05:56Now there is an important thing here: as with working with cells, if I'm going to do this
06:01in the storyboard, and I'm trying to assume that these are reusable header objects,
06:06the same way that my view cells were reusable view cells.
06:09Well, I need to give it an identifier.
06:12If you remember when we worked with the actual view cells themselves, they would have a Reusable
06:18View Identifier called wordCell, and if I select the header I also get a reuse identifier here.
06:25Again, if it's difficult to grab, then make sure that you open the dock instead, select
06:30the header itself, and select its reuse identifier. You don't want to mix these up.
06:35So I'm going to use a Reuse identifier of header.
06:38Now if run this, I will still get nothing.
06:41I am getting that spacing going on, but just as with the individual cells that I need to
06:47provide that cell for item at index path method to actually make sure they're created,
06:52I need to do the equivalent for the header as well.
06:55So jump back I am going to go into my View Controller code, use the Jump bar and just
07:02to jump down to cellForItemAtIndex path.
07:07This is where we are dequeuing the individual cell items and setting their contents.
07:12I need to do something very similar to this, it's a different method, so I will create myself a bit of space here.
07:17But it is on the collectionView, and what I am looking for is--actually it's the very last
07:22one here, it is collectionView: viewForSupplementaryElementOfKindAtIndexPath.
07:30What does that mean, supplementary element of kind? It's a supplementary element of some kind, what kind?
07:35Well, it could be a header, it could be a footer, so it's a specific method that we use
07:39to grab these supplementary reusable views.
07:43That's all we want, and what I want to do is actually be able to get a reference to my
07:49custom WordHeader class that I just wrote, but this view controller class doesn't even know that one
07:54exists, so I better jump up to the top and import it, #import "WordHeader.h", and then
08:02I'll use my jump bar just to jump right back down to viewForSupplementaryElementOfKind.
08:12I can create a pointer to this, I will call it header.
08:17And the way that I get to it is quite similar to asking the collection view for a dequeued
08:23reusable cell, instead I am going to ask the collection view to dequeue a reusable supplementary
08:30view, and there is an extra parameter here, where it's saying well what kind because I
08:34know it's not just the same cell, it could be a header, it could be a footer.
08:38This parameter is typed as an NSString, but there is actually a useful enumeration that we can just use.
08:43If I start typing UICollectionElement, there we go.
08:47There's two options here, UICollectionElementKindSectionFooter, it is a Section Footer or it's a Section Header.
08:54Well, we are interested in the Section Header.
08:56You are drawing the distinction or telling the Collection view to make the distinction
09:00here so it knows how to do the proper sizing and spacing and everything.
09:04Now we still have that Reuse Identifier, because theoretically we could have multiple different
09:10kinds of header view. We only have one, but it doesn't know that.
09:15So I will just put in the Reuse Identifier, and we would call it header.
09:20And the last parameter here for index path, well, that's actually being passed directly
09:24in as index path, so I'll use that.
09:28So now we should have a header object, and because it is my custom class, I should be
09:33able to use .syntax and jump right into, there we go, my header title that I just defined and set the text.
09:41I could do a switch statement here to do some custom stuff, but for purposes of time
09:45I am just going to give it a literal string of Category goes here.
09:51Finally, return that object, save it, run it, and now we have the headers appearing above every section.
10:05Creating a custom footer is essentially following exactly the same process with a few
10:10different names, footer instead of header.
10:12One thing to be aware of is actually in this method.
10:16The one that we have just added which is the viewForSupplementaryElementOfKind, this would
10:21be called when it's looking for a header, this would be called when it's looking for
10:24a footer, and we'd have to make that we were instantiating the right class.
10:28So if you didn't need to do that, you are just going to put in basically an if statement,
10:33that asks what is the kind, so if kind is equal to, and we have these UI Collection
10:40Element Types is it equal to the section header? If so, we are going to go ahead and dequeue
10:45header, if it's equal to footer, we'll go ahead and dequeue a footer.
10:48There only are those two kinds, so it really is just an if/else.
10:52But I only have a header, so I don't need that, I just need to make sure that this is
10:56going to return some object of the right type. And that will do it for the time being.
11:01For the purposes of this What's New in IOS course, this is what we are going to cover for Collection Views.
11:07As you can probably tell this is a deep and very customizable area of iOS development,
11:12and I could do an entire course on collection views, getting into deletion or dynamic updating or even custom layouts.
11:19And you might want to keep an eye out for that at lynda.com.
11:22But hopefully this will be enough to get you started, and next, let's take a look at some of the new frameworks.
Collapse this transcript
3. Working with Passbook
Introduction to Passbook
00:00I'm going to begin with the idea that you've seen there is a new built-in app in iOS called
00:05Passbook, but you might not have really explored it yet.
00:08So this application is part of iOS.
00:10It's already there on the iPhone when you have iOS 6, it's also on the iPod touch with
00:14iOS 6, but isn't on the iPad, it's just on the smaller iOS devices, at least at this time.
00:20It is also on the iOS Simulator, which can be very useful.
00:24It's an app designed to hold coupons, store loyalty cards, boarding passes, event tickets, and so on.
00:30I've loaded a few into my simulator already.
00:33The idea is that this Passbook app is a single application that can store these kinds of
00:38things for multiple companies, multiple stores, multiple airlines, or venues, and you keep all
00:43of your passes in Passbook.
00:44But there are a couple of important points to understand.
00:49Passbook is not an application for generating passes, meaning it does not create unique
00:54coupons or provide unique event tickets.
00:56And neither is it an event management system, it doesn't handle pass redemption.
01:02It is simply a place that can store your passes, your coupons, your tickets that you or some other company define.
01:10The idea is that if you're an airline, for example, you already have an existing system
01:15that creates unique boarding passes, and you already have the physical scanners at
01:20the gates to read them back in. Apple is not trying to replace that.
01:23But now instead of emailing a PDF of that boarding pass to your passenger and having
01:28them printed out, perhaps even having them have to wander around strange hotel at 5 a.m.
01:32in the morning, trying to find the business center and a working printer.
01:36You send them this electronic version instead.
01:38And when they get to the gate of the airport, the airline scans it in to that existing system.
01:43If on the other hand, your store, the expectation is you already have a system to manage loyalty
01:50cards or gift cards and handle those, this just provides another place to store that information.
01:56Same as if you're working with events, the assumption is you already have a system that
02:00could be generating tickets and a system in place to validate them.
02:03So it isn't intended to replace any of these. It's intended to supplement these existing systems.
02:09Now you see barcodes on these examples that I'm showing you here, you don't have to use
02:14a barcode, but it's commonly expected that you would do.
02:18The Passbook app already has built in support for common 2-D barcodes, it supports QR, Aztec
02:25and PDF417, but it does not have built-in support for what are call 1-D barcodes, the
02:32single level ones, like a common UPC code that you might see on something get at the grocery store.
02:39Certain third parties are actually trying to support these right now, but just be aware
02:43that Passbook out of box supports the 2-D ones.
02:47The reason for that is that 2-D barcodes are much more reliable to scan optically rather
02:52than using the laser scanners that the 1-D barcodes support, so it's just more reliable
02:57to use the 2-D versions on a backlit device like an iPhone.
03:00Now you might look at this kind of information and think, well, this is nothing new.
03:05I've seen different companies create their own applications to manage their boarding passes,
03:10and sure that's completely true.
03:11But there are a few benefits from using Passbook.
03:14One, because Passbook is integrated into iOS, it's also integrated into the lock screen,
03:19and what that means is if I go to the lock screen of my device here, I can get things
03:24like a boarding pass actually show up on the lock screen, but only when it's relevant.
03:30I can have a time and a location built into this pass so that the text that I'm at the airport
03:34at the right location and at the right time.
03:38So it doesn't clutter the screen up with a boarding pass for a flight that's not 'til next week.
03:43And one of the benefits here is you can actually get to this pass details directly from the
03:47lock screen, I don't have to unlock the phone and type in any code that I might have,
03:52I just drag this icon and slide it, and it'll go directly just to that pass.
03:58And this is not considered unlocking the phone, the phone is still locked.
04:02So getting there really quickly very convenient if I'm standing in the queue at the gate by
04:06the airport, and when you're viewing one of these passes, Passbook will automatically adjust
04:11the brightness on the iPhone to be the best brightness for scanning these codes.
04:16And it'll also extend the time that this pass would be shown before the iPhone goes back to blank again.
04:23So what we need to do when we're working with Passbook is handle the information to get
04:28our pass into one of these pre-provided formats.
04:32Apple has provided five pass styles in Passbook with different layouts. There's one specifically
04:38for boarding passes for airline or train or boat.
04:43There's a style for managing event tickets, if you notice there's a slightly different
04:47visual look to the edges of most of these.
04:51If I select coupon one, you'll see there's a perforated edge here, that's a different style as coupon.
04:59There's a built in style for a store card, and finally one that's considered generic,
05:05pretty much anything else.
05:06Now you can provide your own colors, you can provide your own artwork and logos.
05:10But really what you're doing a lot of the time is providing the correct information
05:14to fit into these templates.
05:16So here's the second important concept to understand.
05:19To work with Passbook, to create your own passes, your own coupons or tickets or store
05:24cards or whatever they are for Passbook, you do not need to build an iOS application, it's not necessary at all.
05:31To understand why we need to ask, well, how do these passes get into in our Passbook application?
05:37How would I get a boarding pass from Delta or a coupon from Starbucks or a movie ticket
05:42from Fandango into this application right now?
05:46There's three ways to get a pass into the Passbook app right now.
05:50First is email, the same way that an airline right now might send you a PDF of your boarding
05:56pass, they could send you a Passbook pass file that's recognized by iOS.
06:00If you open it up in the Mail application, you can just touch it and import it directly into Passbook.
06:05It's a self-contained file called a PKPASS file.
06:09You can get it here, you can preview it, add it into Passbook.
06:12Now the airline might send you both a PDF and PKPASS file, whatever's most useful at the time.
06:18Second, with a URL, so by downloading from a web page, say I sign on to the site for
06:24a movie theater, I buy a ticket and their confirmation page can generate a URL for me
06:29to download that pass file, that PKPASS single file.
06:34And on iOS 6, it would open up in Passbook.
06:37Apple have even suggested badges for me to place on a website for this.
06:41Now third, I could if I wanted to do it from another iOS application.
06:47If I currently have an app installed on the user's machine, I could generate these passes
06:52in my app using the new Pass Kit framework to get them into Passbook.
06:57But most commonly the passes will arrive on the user's machine via email or downloaded from a URL.
07:03And this means the actual passes that we're creating, those PKPASS file, they're typically
07:09created by a back-end system somewhere, on a website for example.
07:13And here's the great thing, a PKPASS file is actually pretty simple to create.
07:19Although it's delivered as one single file, which if you had it on your Mac desktop,
07:23it might just have a PKPASS suffix. It's really a zipped Archive.
07:31If I rename this to zip, I can then expand it into its own folder, and I can see the contents of that.
07:40It's a bundle. It's got a few icons, an image or two, and very importantly a text file that contains
07:47the information to be shown on the pass.
07:49Now this is not in Objective-C or some other language, it's actually in JSON, JavaScript Object Notation.
07:58It's a very simple way to package up some pure data in key value format, we're going
08:03to explore these in just a moment.
08:05The reason that it's in JSON is because JSON's are really simple format that a lot of back-end
08:11web server-side frameworks are great at generating, Ruby or Python or ASP.net.
08:16And it's much more likely that that's where you would want to generate your passes.
08:23So this pass that I have isn't a program, it isn't an application.
08:28There's no executable code in it, it's just a little bit of text and some artwork,
08:32all zipped up and given a name.
08:34You can also include localizable strings to support multiple languages.
08:38However, to get these into an iOS device, these passes do need to be digitally signed
08:43in the last step of generating this PKPASS file so that someone couldn't pretend to be
08:48Delta and Starbucks and Fandango all at once. So the pass files will always have a signature.
08:54And these passes will get added to Passbook application, someone uses them, and when they're
08:58done with them, they can just choose to delete that pass file.
09:05So to start to create our own, next let's get a little bit more hands-on with what a pass is actually made of.
Collapse this transcript
Creating a custom pass
00:00The first place to go when creating passes for passbook is actually to the Apple Developer site.
00:06Specifically, developer.apple.com/passbook, because here you'll find some references that
00:11aren't included in the basic iOS SDK that you're going to need, or least you're going to want them.
00:17Now if you're working with passbook you'll almost certainly want to bookmark this page.
00:20It will be very useful.
00:24The several documents here that are great to have on hand, and there is also a downloadable
00:27batch you can get you, too, to add to your websites and emails to say that you support Passbook.
00:32But what I'm really interested in first off is this, the Example Passes and Sample Code,
00:38and you do have to be signed-up member of the iOS Developer program to get these.
00:47The Passbook Support Materials are just a dmg, which I'm going to grab and download
00:52so a disk image that will open up in finder.
00:58And apart from the Read Me file, there are three folders here, this first thing is a
01:03bunch of example Passes, there is one pkpass file provided for each of the five provided
01:09times, BoardingPass, Coupon, Event, StoreCard, and Generic.
01:12So, you get the signed bungled pass file that you could just email to yourself or even drop into the simulator.
01:20But you get also all the resources used to make them. We're going to explore these in just a second.
01:26But also in these resources you find signpass. This is a simple Xcode command line project
01:33that we can use to sign our passes so that we can test one on our device or on the simulator,
01:37and that's really useful for us as developers, because again, Passbook will not accept a pass
01:41that hasn't been digitally signed.
01:43But most typically, you won't actually be creating your real passes using an Xcode command line project.
01:49So, the third resource you get is this one, it's a ServerReference, it's a reference implementation
01:56for a server-side application that creates and signs Passbook Passes.
02:00Now this is actually written in Ruby so if you are saying building a website rails app,
02:05it would be a great thing to have on hand, but as it's Ruby its also very readable, even
02:09if you're going to end up building your passes using ASP.NET or PHP or Python or Java or
02:16whatever server-side application you have.
02:19Now in this course we won't be getting into the server-side of things, because once you're
02:22familiar with a few things like the JSON format of a pass, it really has nothing to do
02:27with iOS, so I'm going back in to the Passes directory.
02:31Let's take this BoardingPass example that I have here, BoardingPass.pkpass.
02:36I'm going to open up my simulator, because it's embedded inside Xcode I actually use
02:40Xcode menu to open up the iOS Simulator, but if you find yourself using it a lot what you
02:46can do after you've opened an app from Xcode is you can right-click the icon
02:52and choose to keep it in the dock.
02:55So, open that over on the left, and I'm going to drag in BoardingPass.pkpass here.
03:03Now the effect that I get here is the same that I would if I had open this up, say, in Safari.
03:09In fact, that's what's happening, it is opening up in Safari on this Simulator
03:14device and giving me this preview here.
03:16I can take a look at this Pass, I can flip the little eye button to look at the back of it.
03:21It hasn't been added to a Passbook yet. I can either cancel adding it to it,
03:25or I can click the Add button.
03:27And there's little animation there as it's added to all the other passes.
03:31So, now let's take a look at the resources that were used to create this.
03:38If I go into that BoardingPass.raw folder, I get five files, but there's really just three things.
03:44There is a logo, an icon, and the all-important pass.json file.
03:49The logo and icon are just provided twice.
03:52One regular and one high-res at sign 2x version that will automatically be used for retina display.
03:58So, what's the difference between icon and logo?
04:00Well, the icon is what is used as an icon for this pass file when it's sent in email
04:04or shown on the lock string.
04:06Whereas the logo is what's actually going to be used at the top of the pass when we
04:11are looking at the pass in Passbook itself.
04:15I still have several of those sample passes here, including a couple of duplicates, but
04:19if you notice several of these logos here are using the old white format, that is actually
04:24what Apple officially recommend.
04:26If you have a monochrome version of your logo, that you can show here, to do that one.
04:30We'll talk about those in a bit later. The all-important file here is pass.json.
04:35I am going to open this up in Xcode, it doesn't have to be Xcode, there is nothing special
04:40about this, you could use any text editor or programming editor.
04:43We are not in the world of Objective-C in iOS projects, we don't need to be.
04:49So, here's the data for this boarding pass in JSON format, which is a simple set of nested key value pair.
04:56I don't expect it all to make sense, but it should seem reasonably readable as I start to pass through this.
05:03It's meant to include the information for a particular boarding pass.
05:07So, could I scan little segments of code here and say, well, I have got passenger is
05:11John Appleseed there, I've got a departure time and a flight number.
05:14So, can I make a pretty educated guess as to what information in this JSON file is actually
05:20being shown in the pass itself? And sure I can do.
05:23Now looking through JSON file, I can see that they seem to be split up into few different
05:28sections, we have an area called primaryFields, we have secondaryFields, we have auxiliaryField.
05:33Now if I go down even further, we have a section called backfields.
05:38The backFields are what would be shown on the back of the pass.
05:42We see here a key for a passport for Canadian and residents, and that's what actually
05:46is showing up in the pass over here as well as the terms of use.
05:50Now some of this JSON file is different for each of the different five pass styles.
05:56Boarding passes have one set of expected information, StoreCards have a slightly different set,
06:01events another and so on, but it's all fairly similar.
06:05And particularly the stuff near the top is almost exactly the same.
06:08Now the question is, well, how would you know?
06:11We can get a lot of this information from the passbook for Developers web page from
06:16one of the documents there, which is known as the Passbook Package Format Reference.
06:21This is actually a fairly small document.
06:24But this is what describes the actual pass files themselves.
06:27We have a Package Structure section.
06:30Talks first about the images you can include like the icon and the logo that we already saw
06:34and then gets into the keys in the JSON file itself.
06:42Top level keys like description and organization name, I'm going to drill into this in a little bit.
06:47But the idea is that you need to roughly understand this format, but you don't need to learn it,
06:53you're not going to be manually writing JSON files.
06:56This is going to be generated by your server- side system and read by your Passbook application.
07:01JSON is a format that's intended to be written by one computer and read by another.
07:06So, once you've got it working, you don't even want to see it anymore.
07:09But it is worth experimenting with these files, with changing a couple of them
07:13so we can follow the process of creating a pass and understand what our server-side
07:19technology would need to do. So, next up, I'm going to create one of my own.
Collapse this transcript
Configuring the pass.json file
00:00I am going to make my own coupon pass for Passbook.
00:03A coupon is the simplest pass so we can explore some of the options available in the pass.json file.
00:08So, I have the Passbook Materials disc image loaded here, and inside Passes I'm going
00:14to grab the Coupon.raw folder because it's on our read-only disk image.
00:18I am going to drag it over to my desktop to make my own copy of it.
00:22Go into that folder and what I'm interested first off is the pass.json file,
00:30and I'll open that up in Xcode.
00:33Again, you can use any editor you want, there is nothing special about Xcode here,
00:37we're just working with a single file, not working with any kind of project.
00:40Now when you start to really work with these, one thing that's useful is to go to that Developer
00:45Passbook page and make sure that you have a copy of the Passbook Package Format Reference on hand.
00:51You can download a PDF version of this if you want to. It's a pretty short document.
00:55I think it's less than 20 pages.
00:58So, what I'm going to do with this JSON file is change it.
01:01I don't want to write it from scratch, I'll change what Apple has provided here and make my own one.
01:06Now I want to make a buy one get one free limited time coupon.
01:09So, the top of the pass.json file, this first section is the standard keys needed in every
01:15passbook pass no matter the style. I won't go through every single option, but I will
01:20talk about the most important ones.
01:23The first one at the top here is the passTypeIdentifier, this is very important.
01:27It must be the same as the certificate will use to sign the pass.
01:31I haven't made the certificate yet, but I will do that in a moment.
01:35So, this value here, pass.com.pawplanets.coupon, is the one Apple were using.
01:41So, I need to use one for me or for my organization.
01:45The way these are written, they are quite similar to things like organization identifies
01:49that you'd use when creating a project, and that it's usually written reverse DNS style.
01:54So, com.mycompany.something, though for passbook it should also start with pass dot.
02:00So, I'll have pass.com., and I'm going to say twotreesoliveoil.coupon, twotreesoliveoil
02:10is a website name that we often use at lynda.com for examples and they should make my pass
02:17type identify unique. Nobody else should be attempting to sign passes with that same ID.
02:22Beneath that we have serialNumber, this is completely up to you but should be a unique
02:26string, so you can track whether it's been used or not.
02:30Again, the tracking of whether a coupon has been used is completely up to you.
02:34Passbook doesn't care, it's just a place to hold a unique ID.
02:38This doesn't need to follow a particular format.
02:40Although no two passes that you create under your pass type identifier should have the same serialNumber.
02:46Again, this would usually be generated by your back-end system.
02:49So, I am just going to put something vaguely random in here.
02:56Under this we have teamIdentifier. Well, this is not random. This is the 10-character team ID
03:02you can get from the developer portal.
03:04If you're part of an iOS develop team or have a team ID, if you are just an individual you'll
03:08have an individual ID, and you can use that.
03:11It's not hugely important for what we are doing here, but we do need it in this file,
03:16and the idea is that if I use this team ID for creating my passes, and then I publish
03:22an iOS app to the App Store that uses the same team ID,
03:26well, that app can access my passes and passbook and get to them programmatically.
03:31So, I'm just going to type in my own ID that I have.
03:36Below that we have authenticationToken and webServiceURL, these two lines are worked together.
03:42They can be used if we want to support dynamically updating this pass over the web.
03:47Now that would be done using Apple's Push Notification service, which is beyond the
03:51scope of this introduction, and it would be overkill for a coupon anyway,
03:55so I'm pulling both of these lines out. Next we have barcode.
03:59As I explained earlier we work with the most common 2D barcodes, that's the built-in support in Passbook.
04:06This one is using the PDF417 format, and you can pretty much say anything that you want
04:11to, it could be a completely unique message, it could be just the address of a web page,
04:16or a website, it's totally up to you.
04:19messageEncoding is pretty much always left to iso-8859 classic Latin encoding.
04:26Now very briefly talk about locations here Locations is part of the idea of something
04:31called relevance of a pass.
04:33Now it can either be location, or it can be a date.
04:37With locations you get the opportunity of giving it several potential position of longitude
04:43and latitude and depending on the pass you select, that can mean that, that pass will
04:47appear in the lock stream when it's detected you're at that particular location.
04:51If you are working with a boarding pass, you can also use a particular date.
04:55I'm not really interested in either for the purposes of this example, but this is
05:00the whole idea of relevance.
05:02A coupon that we're doing here can work with location as relevance, it cannot work with date.
05:07And you'll find more information about that in the package reference guide.
05:11After this things get a little easier, we get a bit more obvious options here, organizationName,
05:17logo text, and description.
05:19So, we'll change the organizationName to Two Trees Olive oil as well as the logoText, which
05:24is what will show up on the actual pass itself, give it a basic description here that's used
05:31by the accessibility parts of iOS.
05:35Now we have foregroundColor and backgroundColor, think of this as pretty much
05:41the text color and the background color so I am going to leave the text at 255, 255, 255, which is white.
05:47Again, just a more muted background, and I'll pick this. Then we jump into the primary fields.
05:53I'm going to change this so it changes our offer to Buy one get one free, and that we
06:02expire on the 31st of March.
06:07And finally, in here we have the area called backFields. This is what's on the back of the
06:12pass, when they flip it over it's got an example TERMS AND CONDITIONS, you can have anything you want here.
06:17The thing about backFields is you pretty much just copy this general format, inside the
06:22square bracket, I can put another set of curly braces and inside that just key value pairs
06:29to match the whole key, label, and value setup.
06:35And that should pretty much do it, I am going to save that JSON file, and in my excercise
06:42files for this chapter, I do have a couple of logos that I can use here, just kind of
06:48drag them into the coupon and replace them.
06:52For my examples, I am just going to use logo and logo at sign 2x, I am not going to bother with the icon here.
06:58Again the recommendation from Apple is that if you have a monochrome version of your logo
07:02all in white, then use that. For information on the logo sizes, just go to the Passbook
07:08area of developer.apple.com, go into Passbook programming guide, and you'll find a section
07:15called Pass Design and Creation and in that images fill there allotted spaces, and there
07:20is information in here up on the suggested sizes for things like icons and for things
07:25like the logo image, how much space do you have to play with.
07:29So, I have everything now ready in this folder.
07:33I want to be able to bundle these all up and sign them and turn them into a pass.
07:37So, next we'll see how to sign these, package them up into a single pass file.
Collapse this transcript
Signing and using a custom pass
00:00I have all the pieces ready in a folder on my desktop, but I need to have a certificate
00:04set up with Apple to allow me to sign this pass.
00:07So, I am going to jump over to the Developer site and into the iOS Dev Center, sign in,
00:14and then go to the Provisioning Portal.
00:16There has been a new section added to the portal to support Passbook, which is Pass
00:20Type IDs over here on the left-hand side.
00:23Now with the idea that I'm using here, I actually don't have one, so I am going to click the
00:27button to create a New Pass Type Identifier.
00:31First, I give it a description, which is pretty much anything I want, something meaningful.
00:34Well, this is going to be for creating coupons for the Two Trees company.
00:38So, I'll call it Two Tree Coupons, and then we have to give it the formal identifier.
00:43This is the part that must match what we have in our JSON file in that reversed DNS format.
00:49So, for me its going to pass.com, there we go, twotreesoliveoil.coupon, and you can double-check
00:57in your JSON file just to make sure what you have in that first pass type identifier section.
01:02This needs to exactly match what you're doing for the certificate as well as this teamIdentifier
01:08needs to be either your team or your individual ID in the portal.
01:12So, back over here, this looks correct, I am going to hit Submit.
01:16Now we have that ID, but we don't actually have a certificate for it yet.
01:20So, I need to go ahead and click this Configure button and then in this screen click the Configure button again.
01:26We now need to get set up for a little bit of back and forth with Apple, because what
01:30I'm asking for is a certificate.
01:33It's going to give it to me, but I need to generate something on my end so that I can
01:37sign passes on this computer.
01:39So, it's telling me first to launch Keychain Access on my own computer, so I'll bring it
01:44up there and then from the Menu go down to Certificate Assistant and Request a Certificate
01:50From a Certificate Authority.
01:53I need to type in my email address, common name, just something meaningful here so that
02:01it has meaning to me when I see it in keychain access, and then I am going to choose to save it to the disk.
02:06Now if you are sitting there thinking how I'm meant to know all this, well it is going
02:09to tell you here on the website exactly what to do.
02:12So, I'll click Continue, and it will save a signing request to the desktop, I'm done
02:18with this part of keychain access, I go back to the website, hit Continue there, it's going
02:23to ask me to upload that file. So, I'll choose it and click Generate.
02:29Now it's going to generate me that certificate and in a moment give me the option to download it.
02:35I'll click Continue and Download.
02:38And I don't just want to download it, I want to install it.
02:41So, I'll go and find where it was downloaded, I have a couple from before so I am going
02:46to remove the older one that I have to the trash that's the new one that I just downloaded
02:50here, and I'll double-click it, which will install it into Keychain access.
02:57I actually should be ready to go, I'm done with the Provisioning Portal. Well, what next?
03:02Well, I need to run a little program to actually sign this, to combine all these files together
03:08in this folder into that signed pkpass file, and the way I am going to that is jump into
03:13my Passbook Materials, that disk image that I downloaded from the Apple Developer site,
03:18and I'm looking for this, the signpass project.
03:21I'm going to just copy this to my desktop here just so I have a copy that I can change
03:26and alter if I need to.
03:29Open it up in Xcode. I am not going to change anything about this project but I am going
03:33to go ahead and just to Run, which is going to build it and compile it into an executable
03:38on my disk which I am going to use in a moment.
03:40But the most useful thing it does is pop up a little message telling me how I'm supposed
03:45to use it, which is the name of the program signpass, a little flag -p, and then I give
03:50it a path to the contents of the folder, or actually to the folder itself.
03:55I can optionally give it the path to a certificate.
03:57I won't need to do that because my certificate is already loaded into Keychain access
04:02for everything I do on this machine. So, how do I get to this application?
04:07Well, if I expand my files over here in the Products folder I should see the compiled
04:12executable, because it's Xcode it's put up this derived data this rather long location,
04:17which is fine, I could copy it to my own Documents folder or some other location.
04:22But for purposes of time, I am just going to right-click the executable file and choose
04:27to show it in the finder and then right-click it and click Get Info.
04:31And I am just going to copy the path to that location, Command+C, and open up a Terminal
04:40window, just increase the front a little bit, paste in the path, that will take me take to
04:45me the folder, so then forward slash, and the program itself is called signpass, -p and
04:52a space, and then the address of the folder that contains everything that I want to package up.
04:57Well, that's in my Home folder so ~/Desktop, and it's called Coupon.raw, and here is where
05:06I find out if there's any issues with any change I made to the JSON file.
05:09What is starting to do here is give me these messages that it's starting to combine all
05:14these PNGs together. I do get a message here saying couldn't find a pass type identifier in the past.
05:20Well, I know there is one there. This is the common error you'll get if you make any mistake
05:25with the JSON file, you forget to close a curly brace or do something like that.
05:29So I'm going to jump back over into the JSON file itself, open that up with Xcode, and
05:39I could scan it but I actually know where I made a mistake here.
05:43Which is down near at the bottom.
05:44In the last movie, I'd added some extra back fields here, which was a set of key it has
05:49for just a phone number, it can be whatever field I want, but I really needed a comma after
05:55the closing curly brace here and the opening curly brace here.
05:58So, I'll try that I'll save it, close that one down, go by to my Terminal window, just
06:05hit the up arrow to find that previous option, hit it again.
06:10Now this looks good its actually asking me does it have access to get to my Passbook keys?
06:14And yes it does, I'll say Allow, I could say Always Allows as well.
06:18We don't get any kind of message saying that worked successfully, but if I go and look at the
06:22desktop, I have Coupon.pkpass that's the signed pass file.
06:28So, let's make sure this works. I am going to open up my iOS Simulator.
06:31If you don't have an icon to it, again, open it up through Xcode.
06:34I am just I am going to jump into Passbook first just to let you know I have deleted
06:39all the passes that I had in there.
06:40So, my passbook is empty and now go ahead and drag this into the simulator, it will open
06:46up in Safari, and let me take a look at this.
06:48I have got my logo loading in, I've got my backgroundColor and foregroundColor of white,
06:52I have got this Barcode being generated.
06:55If I flip to the back, I have that phone number that I've added to the back fields, as well
06:59as the terms and conditions, looks good. I am going to click Add.
07:06Now I should be able to find that in Passbook and use it whenever I want to.
07:10view it, switch to the back, and when I'm done just hit Delete.
07:18And that is the process for configuring, creating, and signing a pass.
07:23Now if you are going to substantially get more into Passbook, then the Passbook for Developers
07:27page is your primary jumping off point.
07:29You'll find information here on everything we just covered as well as taking it further,
07:33like working with push notifications to update passes that are already in passport, like being
07:39able to push a changed gate or departure time to a boarding pass.
07:42And there is also information here on working with Pass Kit, which is the fairly small framework
07:49that Apple provides if you want to actually work with Passbook passes within an application itself.
07:56And there's references here on the Passbook web service on downloading Passbook images,
08:01badges you can use in your own emails and your own websites.
Collapse this transcript
4. Additional Frameworks
Posting to Facebook with the Social framework
00:00In iOS 5, Apple integrated Twitter support directly into iOS, and now with iOS 6, they
00:06have added Facebook support and support for the Chinese blogging service, Sina Weibo.
00:13These three services are directly integrated into iOS.
00:17What I mean by integrated is not that there's a Facebook App or Twitter App right out of the box.
00:22But there are system-wide settings in the operating system itself that allow the user
00:27to be signed into one or more of these services, and this one setting is then accessible across
00:33all the apps on the device.
00:35For me, even on the simulator I immediately get Twitter and Facebook settings.
00:39I don't see weibo here, by default it doesn't turn on unless its detected some kind of Chinese
00:44support activated in the operating system.
00:46But if I'd activated say a Chinese keyboard, I'd suddenly see that appear in the settings as well.
00:52And your application can detect if the user is signed into any of these and use that information
00:57to post directly to the account.
00:59And there is a controlled and formalized presentation to do this automatically using a slightly
01:04different user interface for each service.
01:07So to work with this we work with the new Social Framework in the iOS 6 SDK that makes
01:13it very easy, and the Social Framework is a very simple framework, there are only two classes
01:19here, and we're really only interested in one of them.
01:22Now if you used Twitter integration in iOS 5, you use the Twitter framework.
01:26We'll note that the social framework basically replaces it.
01:29The Twitter framework is now officially deprecated, you shouldn't use it anymore because the social
01:34framework supports Twitter and does everything the Twitter framework did.
01:38So there are only two classes in this new framework, the user interface is already provided,
01:42and it even works on the simulator, so let's see how to post to Facebook right out of our application.
01:48I'm going to jump over into Xcode where I have made a very straightforward one-button application.
01:54All I've done here is add a button called post to Facebook and just connected up to
01:58an IBAction called composePost.
02:00Well, what I need to do first is this is a new and separate framework, so I'm going to
02:06need to link to it, I'll jump to my PROJECT settings, select TARGETS, and go over into my
02:11Build Phases where I will link it with the new library, select Social.framework, and Add.
02:22Next up, jump back into my ViewController implementation file, and I really need to do
02:27an import statement for that social framework header file.
02:31But here using the angle brackets because it is a built-in framework.
02:40That's my setup done, now I can jump into this new composePost method that I've added.
02:44This is what's called when the button is touched, and this is all I need to do, I'm going to
02:49generate an instance of the new SLComposeViewController, call it socialPost, and rather than an alloc and init,
03:02I'm going to call the method of the SLComposeViewController that is composeViewControllerForServiceType.
03:11This takes officially an NSString as a parameter, but there are some predefined Enums here that
03:15I can just use which is SLServiceTypeFacebook, one for Sina Weibo, and one for Twitter.
03:22I want the Facebook one, and that will give me that viewController, and all I need to do
03:27is nothing special, just call self presentViewController, we'll make sure to animate it, and I'll just
03:38set nil for the completion handler, two lines of code, save that, run it.
03:46The application opens, I have this button, post to Facebook, it pops up this modal Facebook sheet.
03:54I can type in some text here, I can add the location if I want to, I could cancel out of it.
03:59If I click the Friends options, it actually looks up the account details of my Facebook
04:05account and finds my audiences that I've posted in here.
04:08I don't have many, but I've got some here. I'm just going to select Only Me and then Post.
04:14That's it, one of the reasons this worked is I was already signed into this account on the simulator.
04:20If I hadn't been, it would have thrown an error telling me that it can't do that and can you
04:25go to the Settings and sign in properly. But let's take it a little bit further.
04:31Jumping back in, most typically in a method like this, I'd actually want to check programmatically
04:38to see if they are logged in. Perhaps I'd even turned the button off if they weren't.
04:42It's very simple to do in an if statement, there is a class level method on the ComposeViewController,
04:49so I don't even need to have created an instance of it yet called isAvailableForServiceType.
04:54And we just use the same service type options that I have below ServiceTypeFacebook, ServiceTypeSinaWeibo,
05:03ServiceTypeTwitter. So if that return to I could then create that social post for the
05:09ServiceTypeFacebook and pop it up on the view controller.
05:14Though a word of warning, I'm not going to worry too much about doing this because as
05:18far as I can tell when you're working in the simulator,
05:21the response from isAvailableForService type is always true. It will return true when asked
05:27about any of the three services whether you're logged in or not.
05:31Though it does work fine on an actual device, it just all seems to return true on the simulator.
05:36Now these are my options I can also do after creating this ComposeViewController, but before
05:41I actually present it, we've got methods like setInitialText. That as you might imagine will set initial
06:01text of what you're about the post.
06:06There are also options on it for adding an image, adding a URL, and it all just works.
06:12Now the last thing is the default behavior is either when the sheet is sent or canceled
06:17the modal pop-up is just dismissed.
06:19If you want to capture that happening, you can create your own completion handler that
06:23would pass in to presenting that view controller.
06:27But that's it post to Facebook out of your application and a few lines of code.
06:32Because you may have users that are signed into multiple services, there is another new
06:36control that can provide a more standardized way to choose between multiple ways of sharing content.
06:42But I'll talk about that when I talk about the changes in UI kit.
Collapse this transcript
Improvements to existing frameworks
00:00In iOS 6 as well as the new frameworks like Pass Kit and the social framework, we have
00:05a few additions to existing frameworks worth covering.
00:07Well, technically there are always a lot of minor changes to the frameworks between versions
00:12of iOS, so I am going to quickly cover what I consider the most important changes.
00:16To go into more specifics, take a look at Apple's documentation. First, Maps.
00:21Well, we've had MapKit as a framework for quite some time, but the bit change in iOS 6
00:26is Apple switching off using Google's mapping infrastructure and starting to use their own.
00:31Now this got off to a shaky start, but this is the way we need to use if we want to work
00:36with built-in maps in iOS.
00:39If you weren't aware of this, you now have the Maps app running in the stimulator.
00:43And whether you are using this application to compare or creating your own app, the stimulator
00:48has a lot of features here. It has a menu option for example under the Debug area
00:53to change to a custom location.
00:56And even to recreate a journey at multiple speeds by just passing fake data to the stimulator itself.
01:03Previous versions you could do some stimulation of location and the scheme, but this is a great
01:06way to test an application.
01:09Now if you are writing an app that provides turn-by-turn directions, whether that's for car
01:13or public transport or bicycle or even walking, you can register that app as a routing, or rooting, application.
01:21And what that will mean is your app can show up in search results when people start searching
01:26for particular directions in the Apple Maps application.
01:30And in iOS 6.1 released at the end of January, there is a new class called MKLocalSearch
01:36that allows you to programmatically search for points of interest and addresses the same
01:40way a user might manually search for something in the Maps application.
01:44But although the infrastructure has changed, the core concepts of how you work with maps
01:48and core locations in iOS remains the same. Next, on to EventKit.
01:54EventKit was added back in iOS 4 for working with calendar data, but we've had a couple
01:59of worthwhile additions this time around.
02:01The main thing is we can add, edit, and delete reminders directly from our own applications
02:06and those are stored in the classic EventKit store and they do behave just like the ones
02:11created in the reminder's application itself. They can be time or location based.
02:17The reminders app itself does not exist in the stimulator, so you will need to test that
02:21on a device if you want to prove that it works. I am moving on to a couple of others.
02:26Both the GameKit.framework for Game Center and the StoreKit.framework for supporting
02:31in app purchase are really specific enough to need their own courses but there's a couple
02:36of things here worth mentioning.
02:38In GameKit there is new ViewController called GKGameCenterViewController that clears up
02:43the previous situation where you had to use different view controllers, one to show
02:48achievements and another I want to show leader board information, and it combines them
02:52into one master view controller for the entire game center.
02:55There are also new classes to allow one player to issue a challenge to another and several
03:01improvements to matchmaking and the player display.
03:04I am moving on to this StoreKit.framework that handles in-app purchase.
03:08Well, now you can support purchases of regular iTunes content from inside your app, not just
03:14your own content that you are selling, but standard music, apps, movies, books, and so on.
03:19And one great thing they are also supporting with iOS 6 is Apple can now host downloadable content for you.
03:26Previously if you sold downloadable content in your application, you had to control and
03:30manage that downloadable content yourself, control those service, and provide the ability
03:35for uses to restore previous purchases.
03:37But now you can host it all with Apple, making that story a lot simpler.
03:42So these are worthwhile changes to point out, and then in the last movie, I am going to
03:45cover the changes in the UIKit. framework that we haven't yet seen.
Collapse this transcript
Changes in UIKit
00:00Earlier we spent some time going through auto layout and a great new collection views in
00:05iOS 6, but there are some other improvements we should explore about the commonly used classes.
00:10Now one of the reasons for doing this is it's very easy to get into the habit of using our
00:14favorite classes without realizing that there may have been some big changes to them.
00:20So to get us started, let's talk about UITableView.
00:22Well, there was something I did mention in the collection view section, but I will make
00:26it explicit here, there are improvements in reusing cells in a Table view.
00:32One of the classic methods people have been using for years is the dequeueReusableCellWithIdentifier.
00:39We ask the tableView to do this, are there any reusable cells? And typically we would
00:43write a little line of code that says, if that returned nil, well, then we have to go
00:48and make one, we have to go and instantiate one.
00:51But this dequeueReusableCellWithIdentifier now has an additional method with an external parameter.
00:57So it's dequeueReusableCellWithIdentifier for indexPath, and indexPath is always passed in.
01:04The behavior of this is slightly different.
01:06As long as you have tagged the cell on the story board or registered a class with the
01:10tableView this will always return an object.
01:13So cell should never be nil, you just don't need that code anymore.
01:17Not a major change, but something that makes it just a lot more pleasant to write.
01:22Now also when working with UITableView, there are new explicit classes for headers and footers,
01:27and really what they have done here is take a leaf out of the UI collection view stuff
01:32that we explode earlier. So there are actually new object types.
01:35There is a UITableViewHeaderFooterView which can act as either the header and the footer
01:40and then there are new methods like dequeueReusableHeaderFooterViewWithIdentifier.
01:46Very similar to collection views, and it's going to make it quite easy to jump between
01:49the table and collection views as you need to.
01:52Next up is a new control in UIKit called UIRefreshControl.
01:58This is a new standard control to use with a Table view.
02:01It's the official implementation of what has slowly been becoming an unofficial standard
02:06for the last couple of years.
02:08The idea that if you have a Table view of dynamic data and you want to refresh it,
02:14you pull down on it to refresh the data inside it, and you get a little progress bar up at the top,
02:18refreshes the data, you pull down again, this is now being used in the Mail application,
02:23it's used in a lot of Twitter applications, and so on.
02:26So this object now exists formally in UIKit with the animation already built in.
02:32So it's UTRefreshContorl, it's instantiated and added to UITableView.
02:36I do have a simple sample project in the excercise files if you want to see one being used.
02:42When it's pulled down, it kicks off a refresh event, you could use that to go and fetch
02:47some data, when the data comes back, you call the refresh event again, and you make
02:52that little control go away. Not all table views will need it.
02:56For example, if you are working with something like the Settings view, there is no benefit
03:00to pulling down on this and putting in a Refresh control, but it's very nice to finally have it built into iOS.
03:06Next up is an important one.
03:08Autorotation is changing in iOS 6. The classic thing that we have been using for years is
03:13this shouldAutorotateToInterfaceOrientation method. This is officially now deprecated in iOS 6.
03:22It's a slow movement away from this, though. Instead, we have other options.
03:26We have a SupportedInterfaceOrientations method and also a PreferredInterfaceOrientationForPresentation.
03:35The reason for these is Apple is actually slightly moving towards a more flexible, a
03:40more powerful way of handling orientation that gets us past just the default it's either
03:45portrait or it's landscape.
03:47Well, no, it can be a bit more flexible than that when there is views within views and subviews within subviews.
03:54So what I expect to see, shouldAutorotationToInterfaceOrientation
03:58and sample code for some time to come.
04:00Just know that, that is officially deprecated, and you should stop moving on to the new ones.
04:04Now while we are talking about deprecated stuff, if I'm looking at the UIViewController
04:09itself, there is a couple of method you simply should not use anymore, and that's viewWillUnload and viewDidUnload.
04:17Now in the past, these were mainly used for freeing up, releasing things you are holding
04:23onto as part of the whole deallocation process, but with the benefit of arc and better ways
04:28that the view controller themselves are constructed, you simply shouldn't need these anymore.
04:34If you really must use some method for actually getting rid of resources that you are holding
04:40on to, use view will disappear or view did disappear instead or possibly even did receive
04:45memory warning if there is a problem.
04:48But viewWillUnload and viewDidUnload simply should not be needed.
04:51Now there's a few updates to control like the stepper and the switch to support basic
04:56visual customization, and I am going to leave things like that as something that you will
05:00look up and research when you need it, not something really worth committing to memory.
05:04Finally, in this section, the UIActivityViewController.
05:08This is a new controller for working with multiple possible built-in options, when you
05:13have an item that you might want to send to Facebook or to Twitter or to the Clipboard.
05:18Now you've almost certainly seen this if you've spent any time with iOS 6.
05:22For example, if you are working with the photos album.
05:25You select a photo in the album, you click the Sharing button that you find at the bottom
05:29left, and what you get is this modal window will appear with multiple options on it.
05:34Do you want to mail this, do you want to put it in the photo stream, do you want to tweet
05:37this, send it to Facebook, copy it, print it, what do you want to do?
05:41This is the UI activity view controller.
05:44It's very easy to instantiate as the options for it are really based on what else is active
05:50in the system, and it doesn't take much to configure.
05:53You instantiate it with an array of items that could be just a simple text message,
05:58it could be an image, it could be objects if that makes sense, and it will do its best
06:03to pass that information to whatever you choose, Mail or the Facebook sheet or the Twitter sheet.
06:09You can choose to exclude some of these services if you know they don't make sense, but by default
06:15everything that's available would be included on the UIActivityViewController.
06:20This is shown as a modal window on the iPhone, on the iPad it's shown in a pop-over.
Collapse this transcript
Conclusion
Goodbye
00:00Thanks for joining me for iOS 6 SDK new features.
00:03I hope you got a good sense of the most important changes and additions in this version of iOS,
00:08and that you now feel comfortable with things like auto layout and collection views,
00:12how to get started with areas like Passbook and the social framework.
00:15As ever keep a bookmark to the documentation at developer.apple.com as they refine
00:20 and update the references for iOS 6 material and keep an eye on lynda.com for more iOS courses.
00:26Let us know if there is anything you would like to see.
00:28Good luck with your apps, and see you next time.
Collapse this transcript


Suggested courses to watch next:

iOS SDK Essential Training (2012) (6h 26m)
Simon Allardice



Are you sure you want to delete this bookmark?

cancel

Bookmark this Tutorial

Name

Description

{0} characters left

Tags

Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading
cancel

bookmark this course

{0} characters left Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading

Error:

go to playlists »

Create new playlist

name:
description:
save cancel

You must be a lynda.com member to watch this video.

Every course in the lynda.com library contains free videos that let you assess the quality of our tutorials before you subscribe—just click on the blue links to watch them. Become a member to access all 104,069 instructional videos.

get started learn more

If you are already an active lynda.com member, please log in to access the lynda.com library.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Access to lynda.com videos

Your organization has a limited access membership to the lynda.com library that allows access to only a specific, limited selection of courses.

You don't have access to this video.

You're logged in as an account administrator, but your membership is not active.

Contact a Training Solutions Advisor at 1 (888) 335-9632.

How to access this video.

If this course is one of your five classes, then your class currently isn't in session.

If you want to watch this video and it is not part of your class, upgrade your membership for unlimited access to the full library of 2,024 courses anytime, anywhere.

learn more upgrade

You can always watch the free content included in every course.

Questions? Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com.

You don't have access to this video.

You're logged in as an account administrator, but your membership is no longer active. You can still access reports and account information.

To reactivate your account, contact a Training Solutions Advisor at 1 1 (888) 335-9632.

Need help accessing this video?

You can't access this video from your master administrator account.

Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com for help accessing this video.

preview image of new course page

Try our new course pages

Explore our redesigned course pages, and tell us about your experience.

If you want to switch back to the old view, change your site preferences from the my account menu.

Try the new pages No, thanks

site feedback

Thanks for signing up.

We’ll send you a confirmation email shortly.


By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

Keep up with news, tips, and latest courses with emails from lynda.com.

By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

   
submit Lightbox submit clicked