In this week's lab, you will implement an iPad version of Lab 4.
Like last week's lab, your code:
Before beginning, your Lab 04 needs to be working. If you haven't got that working yet, you'll need to finish that before you can begin this. Ask me for help so I can get you ready for Lab 05.
There is no need to make a new repository for Lab 05 since you are simply extending the functionality of Lab 04.
You should refer to the StudentManager-iPad project we built in class for hints on how to complete this lab.
When you are on an iPad, use a UISplitViewController to display the cards list and their images. The table view controller should be the master view controller, and the card image view controller should be the detail view controller.
Important note: You need to convert your app to work on the iPad. Select "Targets" from the left column menu (it looks like a red bulls eye). Click on your app name (for example, RFTG) and then choose Project->Upgrade Current Target for iPad. Be sure to select "Universal Application".
When you are in Portrait mode, your app should display a button on the right side that pulls down the hidden table view. When you are in Landscape mode, your button should go away.
When the app first loads, there is no image set to be displayed in your detail view. Whenever the image view controller determines that it doesn't know what image to display, display the "cardback.jpg" image. For example, use that image when the app loads. You may also want to use that image when the card set changes, or maybe only when the card set changes and the card you had been viewing is not in the new set.
Note that your app should also support rotation to both portrait and landscape mode in order to fully test the UISplitView. You'll notice that the image size is incorrect when you rotate, so you should use this line in your -loadView method of your image view controller (after you've set up the view):
self.view.contentMode = UIViewContentModeScaleAspectFit;
The Student Manager app contains an example of using a swipe gesture recognizer. You will want to implement something quite similar. When a card image is swiped, you will to show the next (or previous) card in the current set your are viewing.
In -viewDidLoad of your image view controller, you are going to add to swipe gesture recognizers. A swipe gesture recognizer can only detect swipes in one direction. Since you'd like to find left and right swipes, you need to create two recognizers. If you don't specify the directionality of the swipe, it is to the right by default. Below, I am assuming that your view is called imageView
UISwipeGestureRecognizer *swipegr; // right swipe swipegr = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)]; [imageView addGestureRecognizer:swipegr]; [swipegr release]; //imageView has now retained this // left swipe swipegr = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe:)]; swipegr.direction = UISwipeGestureRecognizerDirectionLeft; [imageView addGestureRecognizer:swipegr]; [swipegr release]; //imageView has now retained this
Notice that both gesture recognizers will call the swipe: method when they detect a swipe, so we need to write that method. It will look something like this:
- (void)swipe:(UISwipeGestureRecognizer*)recognizer { if (recognizer.direction == UISwipeGestureRecognizerDirectionLeft) { //do something for left } else if (recognizer.direction == UISwipeGestureRecognizerDirectionRight) { //do something for right } else { //ignore up and down swipes } }
The key here is that when you swipe, you're going to need to tell the table view controller that you swiped. You need to tell the table view controller for two reasons:
This means you are going to need a delegate. You probably had a delegate from Lab 04, but if you didn't, you need one now. (Including all the steps required: declaring the protocol, adding an instance variable, setting up the property, synthesizing the property, telling the table view controller it should adhere to the protocol, implementing the method in the table view controller, and assigning the delegate to the table view controller.) Assuming you had one from Lab 04, you can simply add a new method to your protocol and have the table view controller implement that for you.
NSUserDefaults gives you a persistent store for small amounts of information, usually related to some default configurations for your app. You should read the documentation for the complete API. Here are some examples:
//Read an integer with key "filterSet" out of NSUserDefaults //An integer key that doesn't exist returns 0. int filter = [[NSUserDefaults standardUserDefaults] integerForKey:@"filterSet"]; //Set a value in NSUserDefaults -- does not write to disk [[NSUserDefaults standardUserDefaults] setInteger:filter forKey:@"filterSet"]; //Write the NSUserDefaults to disk [[NSUserDefaults standardUserDefaults] synchronize];
Think about when you need to read the defaults from disk (at the start of the app), when you need to change the defaults (when someone changes the segmented index), and when you'd like to write to disk. Since the data you are writing to disk is so small, you could just write every time the defaults change. Or you could write only when the app is about to terminate or go into the background.