Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Beginning iOS5 Development.pdf
Скачиваний:
7
Добавлен:
09.05.2015
Размер:
15.6 Mб
Скачать

394

CHAPTER 11: iPad Considerations

The split view controller calls this method in the delegate when the left side of the split is about to disappear, and passes in a couple of interesting items: a UIBarButtonItem and a UIPopoverController. The UIPopoverController is already preconfigured to contain whatever was in the left side of the split view, and the UIBarButtonItem is set up to display that very same popover. This means that if our GUI contains a UIToolBar or a

UINavigationItem (the standard toolbar presented by UINavigationController), we just need to add the button item to it in order let the user bring up the navigation view, wrapped inside a popover, with a single tap on the button item.

In this case, since this controller is itself wrapped inside a UINavigationController, we have immediate access to a UINavigationItem where we can place the button item. If our GUI didn’t contain a UINavigationItem or a UIToolbar, we would still have the popover controller passed in, which we could assign to some other element of our GUI so it could pop open the popover for us. We’re also handed the wrapped

UIViewController itself (BIDMasterViewController, in this example) in case we would rather present its contents in some other way.

So, that’s where the popover controller comes from. You may not be too surprised to learn that the next method effectively takes it away:

- (void)splitViewController:(UISplitViewController *)splitController willShowViewController:(UIViewController *)viewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem

{

// Called when the view is shown again in the split view, invalidating the button and popover controller.

[self.navigationItem setLeftBarButtonItem:nil animated:YES]; self.masterPopoverController = nil;

}

This method is called when the user switches back to landscape orientation. At that point, the split view controller wants to once again draw the left-side view in a permanent position, so it tells us to get rid of the UIBarButtonItem we were given previously.

That concludes our overview of what Xcode’s Master-Detail Application template gives you. It might be a lot to absorb at a glance, but, ideally, by presenting it a piece at a time, we’ve helped you understand how all the pieces fit together.

Here Come the Presidents

Now that you’ve seen the basic layout of our project, it’s time to fill in the blanks and turn this autogenerated app into something all our own. Start by looking in the book’s source code archive, where the folder 11 – Presidents contains a file called PresidentList.plist. Drag that file into your project’s Presidents folder in Xcode to add it to the project, making sure that the checkbox telling Xcode to copy the file itself is in the on state. This plist file contains information about all the US presidents so far, consisting of just the name and Wikipedia entry URL for each of them.

www.it-ebooks.info

CHAPTER 11: iPad Considerations

395

Now, let’s look at the BIDMasterViewController class and see how we need to modify it to handle the presidential data properly. It’s going to be a simple matter of loading the list of presidents, presenting them in the table view, and passing a URL to the detail view for display. In BIDMasterViewController.h, add the bold line shown here:

#import <UIKit/UIKit.h>

@class BIDDetailViewController;

@interface BIDMasterViewController : UITableViewController

@property (strong, nonatomic) BIDDetailViewController *detailViewController;

@property (strong, nonatomic) NSArray *presidents;

@end

Then switch to BIDMasterViewController.m, where the changes are a little more involved (but still not too bad). Start off by synthesizing the presidents property near the top of the file:

@implementation BIDMasterViewController

@synthesize detailViewController = _detailViewController;

@synthesize presidents;

Next, update the viewDidLoad method, adding a few lines to load the list of presidents:

- (void)viewDidLoad { [super viewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

NSString *path = [[NSBundle mainBundle] pathForResource:@"PresidentList" ofType:@"plist"];

NSDictionary *presidentInfo = [NSDictionary dictionaryWithContentsOfFile:path]; self.presidents = [presidentInfo objectForKey:@"presidents"];

self.detailViewController = (BIDDetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];

[self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:NO scrollPosition:UITableViewScrollPositionMiddle];

}

Complete the “bookkeeping” part of this class by making the following changes to the viewDidUnload method farther down:

- (void)viewDidUnload { [super viewDidUnload];

//Release any retained subviews of the main view.

//e.g. self.myOutlet = nil;

self.presidents = nil;

}

Now, at some point while looking at this class, you may have been surprised to notice that BIDMasterViewController, despite being a table view controller for displaying a list of items, doesn’t implement any table view delegate or data source methods! Since we’re subclassing from UITableViewController, which implements the required

www.it-ebooks.info

396

CHAPTER 11: iPad Considerations

methods in some basic way, we can get away with that for a while, but now it’s time to start filling in the code so that we can present some data.

Let’s start by letting the table view know how many sections it’s going to have. Add this method at the bottom of the file BIDMasterViewController.m, just before the @end:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1;

}

Technically, this method isn’t really necessary. If it’s not present, the table view will assume 1 as the default number of sections. However, as a point of consistency, including this method makes sense. With the method in place, the number of sections in the table view is explicit and clear.

Next, add the method that tells the table view how many rows to display:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

{

return [self.presidents count];

}

After that, write the the tableView:cellForRowAtIndexPath: method to make each cell display a president’s name:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *Identifier = @"Master List Cell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier]; if (!cell) {

cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:Identifier];

}

// Configure the cell.

NSDictionary *president = [self.presidents objectAtIndex:indexPath.row]; cell.textLabel.text = [president objectForKey:@"name"];

return cell;

}

Finally, it’s time to implement tableView:didSelectRowAtIndexPath: to pass the URL to the detail view controller, as follows:

- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

NSDictionary *president = [self.presidents objectAtIndex:indexPath.row]; NSString *urlString = [president objectForKey:@"url"]; self.detailViewController.detailItem = urlString;

}

That’s all we need to do for BIDMasterViewController. But before we can run this app, we need to make a change to the storyboard. As you will recall from Chapter 10, a UITableView

www.it-ebooks.info

CHAPTER 11: iPad Considerations

397

can be configured to display a fixed set of cells instead of a dynamic collection pulled from the data source. As it turns out, the UITableView in the default storyboard created with this project is configured just that way, so we need to change that.

Select MainStoryboard.storyboard and open the attributes inspector, and then click your way to the UITableView. To do this, find the Master View Controller – Master Scene in the dock list. Open the disclosure triangle to the left of the Master View Controller – Master item, which will reveal the Table View item. Alternatively, you can type table view in the search field at the bottom of the dock. No matter how you got there, select that item.

Once the table view is selected, the attributes inspector will display Table View at the top of the first group of controls. The very first option in that group is Content, which you should now change from Static Cells to Dynamic Prototypes. While you’re there, go ahead and reduce the number of Prototype Cells to 0, as well. We won’t be using the one that’s there by default, and leaving unused, unidentified cell prototypes here will just generate an annoying compiler warning later.

At this point, you can build and run the app. Tap the Master button in the upper-left corner to bring up a popover with a list of presidents (see Figure 11–6). Tap a president’s name to display that president’s Wikipedia page URL in the detail view.

Figure 11–6. Our first run of the Presidents app. Note that we tapped the Master button to bring up the popover. Tap a president’s name, and the link to that president’s Wikipedia entry will be displayed.

www.it-ebooks.info

398

CHAPTER 11: iPad Considerations

Let’s finish this section by making the detail view do something a little more useful with the URL. Start with BIDDetailViewContoller.h, where we’ll add an outlet for a web view to display the Wikipedia page for the selected president. Add the bold line shown here:

#import <UIKit/UIKit.h>

@interface BIDDetailViewController : UIViewController < UISplitViewControllerDelegate>

@property (strong, nonatomic) id detailItem;

@property (strong, nonatomic) IBOutlet UILabel *detailDescriptionLabel;

@property (weak, nonatomic) IBOutlet UIWebView *webView;

@end

Then switch to BIDDetailViewController.m, where we have a bit more to do (though really, not too much). Start near the top of the class’s @implementation block, adding synthesis for the webView property:

@synthesize detailItem = _detailItem;

@synthesize detailDescriptionLabel = _detailDescriptionLabel; @synthesize masterPopoverController = _masterPopoverController;

@synthesize webView;

Then scroll down to the configureView method, and add the methods shown in bold here:

- (void)configureView

{

// Update the user interface for the detail item.

NSURL *url = [NSURL URLWithString:self.detailItem]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; [self.webView loadRequest:request];

if (self.detailItem) {

self.detailDescriptionLabel.text = [self.detailItem description];

}

}

These new lines are all we need to get our web view to load the requested page.

Next, move on down to the splitViewController: willHideViewController:withBarButtonItem:forPopoverController: method, where we’re simply going to give the UIBarButtonItem a more relevant title:

barButtonItem.title = NSLocalizedString(@"Master", @"Master"); barButtonItem.title = NSLocalizedString(@"Presidents", @"Presidents");

All that’s left now is to clean up after ourselves in the viewDidUnload method:

-(void)viewDidUnload {

//Release any retained subviews of the main view.

//e.g. self.myOutlet = nil;

self.webView = nil;

}

Believe it or not, these few edits are all the code we need to write at this point.

www.it-ebooks.info

CHAPTER 11: iPad Considerations

399

The final changes we need to make are in MainStoryboard.storyboard. Open it for editing, find the detail view at the lower right, and start by taking care of the label in the GUI (whose text reads “Detail view content goes here”).

Start by selecting the label. You might find it easiest to select the label in the dock list, in the section labeled Detail View Controller – Detail Scene. You’ll find it quickly by typing label in the dock’s search field.

Once the label is selected, drag the label to the top of the window. Note that the label should run from the left to right blue guideline and fit snugly under the toolbar. This label is being repurposed to show the current URL. But when the application launches, before the user has chosen a president, we want this field to give the user a hint about what to do.

Double-click the label, and change it to Select a President. You should also use the size inspector to make sure that the label’s position is anchored to both the left and right sides, as well as the top edge, and that it allows horizontal resizing so that it can adjust itself between the landscape and portrait orientations (see Figure 11–7).

Figure 11–7. The size inspector, showing the settings for the “Select a President” label

Next, use the library to find a UIWebView and drag it into the space below the label you just moved. After dropping the web view there, use the resize handles to make it fill the rest of the view below the label. Make it go from the left edge to the right edge, and from the blue guideline just below the bottom of the label all the way to the very bottom of the window. Then use the size inspector to anchor the web view to all four edges, and allow it to resize both horizontally and vertically (see Figure 11–8).

www.it-ebooks.info

400

CHAPTER 11: iPad Considerations

Figure 11–8. The size inspector, showing the settings for the web view

We have one last bit of trickery to perform. To hook up the outlet you created, controldrag from the Detail View Controller icon (in the Detail View Controller – Detail section in the dock, just below the First Responder icon) to our new web view (same section, just below the label), and connect the webView outlet. Save your changes, and you’re finished!

Now, you can build and run the app, and it will let you see the Wikipedia entries for each of the presidents. Rotate the display between the two orientations, and you’ll see how the split view controller takes care of everything for you, with a little help from the detail view controller for handling the toolbar item required for showing a popover (just as in the original app before we made our changes).

The final change to make in this section is strictly a cosmetic one. When you run this app in landscape orientation, the heading above the navigation view on the left is still Master. Switch to portrait orientation, tap the Presidents toolbar button, and you’ll see the same heading.

To fix the heading, open MainStoryboard.storyboard, double-click the navigation bar above the table view at the upper right, double-click the text shown there, and change it to Presidents (see Figure 11–9). Save the storyboard, build and run the app, and you should see your change in place.

Figure 11–9. The current state of MainStoryboard.storyboard. We’ve changed the title of the master detail view’s table view to Presidents.

www.it-ebooks.info

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]