navigation in ipads splitviewcontroller. overview create a master-detail application switch device...

35
Navigation in iPads splitViewController

Upload: jean-deirdre-whitehead

Post on 03-Jan-2016

214 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

Navigation in iPadssplitViewController

Page 2: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

Overview

Create a Master-Detail applicationSwitch Device Family to iPad

Give the project a name and click “Use Storyboards” and “Use Automatic Reference Counting”

Save it somewhere. Do not create a git directory

There’s no nib; instead the storyboard represents several views

Page 3: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

The storyboard

Table view for left side (in landscape mode)

splitViewController

Nav controller for right side

Nav controller for left side

View for right side

The left side and right sides (in landscape mode) have separate view and separate view controllers.The right view (called the detail view) is the delegate of the splitViewController.

Page 4: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

Organization

SplitViewController

Left side Nav controller

Right side Nav controller

Left side View(table)

(masterViewController)

Right side View (detailViewController)

delegate

You can push new views on the left side

You cannot just push views on the right side; must maintain the delegate relationship.

You can add subviews to the right side without destroying the delegate relationship.

You don’t see this code

Page 5: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

Organization

SplitViewController

Left side Nav controller

Left side View(table)

(masterViewController)

The masterview controller has two instance variables that allow it to use the nav controller and spltview controller.

You don’t see these variables in the masterViewController.h file, however, they’re inherited.

self.splitViewController

self.navigationController

Page 6: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

delegate

The right side view controller is the delegate of the splitViewController

Why? The right side contains the navigation bar

When the device is in landscape mode, the navigation bar has no button

When the device is in portrait mode, the navigation bar has a button to bring up the popover for navigation.

The splitviewcontroller will call its delegate when the orientation changes to tell the right view when the left view will be hidden.

Page 7: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

Classes

You don’t see the code for the splitViewController or for the two nav controllers.

Page 8: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

Testing

Run.

Page 9: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

Explaining the code

The default master-detail project creates a storyboard splitViewController that includes

A splitViewController (you don’t see the code, just the view in the MainStoryboard)

A navigation controller for the master view (you don’t see the code, just the view in the MainStoryboard)

A master view controller (you see it in the project navigator)

A navigation controller for the detail view (you don’t see the code, just the view in the MainStoryboard)

A detail view controller (you see in the project navigator)

Page 10: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

CMPAppDelegate.h

#import <UIKit/UIKit.h>

@interface CMPAppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end

Nothing new here.

Page 11: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

CMPAppDelegate.m−(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

// Override point for customization after application launch.

UISplitViewController *splitViewController = (UISplitViewController *) self.window.rootViewController;

UINavigationController *navigationController = [splitViewController.viewControllers lastObject];

splitViewController.delegate = (id)navigationController.topViewController;

return YES;

}

The splitViewController is by default the rootViewController in this project.

The splitViewController has an array of 2 Navigation Controllers, the first entry is the left view controller, the second the right view controllerThe navigation controller has one

viewcontroller in it’s stack right now; the detail view controller.

Can’t connect the splitViewController delegate to the detail view controller in IB because you cannot make connections between views in a storyboard. You can make segues between views of course.

Page 12: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

masterViewController.m

−(void)awakeFromNib

{

self.clearsSelectionOnViewWillAppear = NO;

self.contentSizeForViewInPopover = CGSizeMake(320.0, 600.0);

[super awakeFromNib];

}

Don’t let the table selection disappear when the user comes back to this view.

The popover must be at leaset 320 pixels wide. Otherwise, can make any size.

Page 13: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

masterViewController.m−(void)viewDidLoad

{ [super viewDidLoad];

self.navigationItem.leftBarButtonItem = self.editButtonItem;

UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)]; self.navigationItem.rightBarButtonItem = addButton;

self.detailViewController = (CMPDetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];} self.splitViewController.viewControllers lastObject is the navigation

controller for the detail view. The top controller for the navController is the CMPDetailViewController

We’re adding an edit button to the navigation bar.

Now add an insert button.

Page 14: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

CMPDetailViewController.h

#import <UIKit/UIKit.h>

@interface CMPDetailViewController : UIViewController <UISplitViewControllerDelegate>

@property (strong, nonatomic) id detailItem;

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

@end

detailItem will hold the information to be displayed.

detailDescriptionLabel will connect to the label in the view.

Page 15: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

CMPDetailViewController.m

#import "CMPDetailViewController.h"

@interface CMPDetailViewController ()

@property (strong, nonatomic) UIPopoverController *masterPopoverController;

- (void)configureView;

@end

This is a class extension. masterPopoverController becomes a private data instance.

Similarly, configureView becomes a private method for this class.

Page 16: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

CMPDetailViewController.m

− (void)setDetailItem:(id)newDetailItem{ if (_detailItem != newDetailItem) { _detailItem = newDetailItem; // Update the view. [self configureView]; }

if (self.masterPopoverController != nil) { [self.masterPopoverController dismissPopoverAnimated:YES]; } }

−(void)configureView{ // Update the user interface for the detail item.

if (self.detailItem) { self.detailDescriptionLabel.text = [self.detailItem description]; }}

We override the detailItem setter so that we can update the view and dismiss the popover.

If there is a value in the detailItem we set the label in the view to it’s value. Recall that every class has a description method bye default.

Page 17: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

CMPDetailViewController.m

− (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)

barButtonItem forPopoverController:(UIPopoverController *)popoverController{ barButtonItem.title = NSLocalizedString(@"Master", @"Master"); [self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES]; self.masterPopoverController = popoverController;}

− (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;}

These are splitViewController delegate methods.

Create button bar item. Can localize

This method is called when the left side will disappear (iPad has been rotated to portrait mode).The popOverController is passed to us. We need to display this when the button is clicked (done automatically for us).The size of the popOverController was set in “awakeFromNib” method in the masterViewController.

This method is called when the left side will appear (iPad has been rotated to landscape mode).Make button disappear.No longer need the popoverController (the nav table appears on the left side)

Page 18: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

Static tables

We usually want to set the information in the navigation table with predetermined data.

We’ll add an array of president and URL to their wikipedia site.

We’ll use a structure called a plist. This is one of Apple’s structures that makes it easy to store and retrieve data.

It’s actually just syntactical sugar over XML

See

Page 19: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

Plist

First download the file PresidentList.plist from the class webpage

Reference->examples->PresidentList.plist

Put this into your project You can drag it from the Finder to the project navigator

Make sure the checkbox next to “import” is checked

Part of the PresidentList plist is on the next slide. It creates a dictionary data structure.

The dictionary has one item named presidents

The corresponding value is an array of dictionary entries

Page 20: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

plist<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict> <key>presidents</key> <array>

<dict> <key>name</key> <string>George Washington</string> <key>url</key>

<string>http://en.wikipedia.org/wiki/George_Washington</string></dict>

Page 21: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

masterViewController.h#import <UIKit/UIKit.h>

@class CMPDetailViewController;

@interface CMPMasterViewController : UITableViewController

@property (strong, nonatomic) CMPDetailViewController *detailViewController;

@property (copy, nonatomic) NSArray *presidents;

@end

Add this property to store the information.

Page 22: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

masterViewController.m- (void)viewDidLoad{ [super viewDidLoad];

self.navigationItem.leftBarButtonItem = self.editButtonItem; NSString *path = [[NSBundle mainBundle] pathForResource:@"PresidentList" ofType:@"plist"]; NSDictionary *presidentInfo = [NSDictionary dictionaryWithContentsOfFile:path]; self.presidents = [presidentInfo objectForKey:@"presidents"];

UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)]; self.navigationItem.rightBarButtonItem = addButton;

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

Add code to initialize the NSArray of Dictionary items for the presidents.

We no longer need this code to insert an insert button.

Page 23: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

masterViewController.m

Change these methods:

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

{

return _objects.count;

return [self.presidents count];

}

We no longer use the _objects array; instead we use the presidents array

Page 24: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

masterViewController.mChange this method:

− (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *) indexPath{ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];

NSDate *object = _objects[indexPath.row]; cell.textLabel.text = [object description];

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

return cell;}

We no longer use the _objects array, we now use the presidents array. But note that each entry in the presidents array is a dictionary.

Page 25: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

masterViewController.mChange this method:

− (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ NSDate *object = _objects[indexPath.row]; self.detailViewController.detailItem = object; NSDictionary *president = self.presidents[indexPath.row]; NSString *urlString = president[@"url"]; self.detailViewController.detailItem = urlString;}

We no longer use the _objects array

Each entry in the presidents array is a dictionary with two keys, “name” and “url”. Here we get the value associated with the “url” key.

Page 26: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

masterViewController.m

We will no longer have edit or insert buttons, so eliminate these methods from masterViewController.m

− (void)insertNewObject:(id)sender

− (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath

− (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath

Page 27: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

Adding a web view

We can add a web view to actually display the wikipedia web page for a president

We’ll need to change the detailViewController file

Will also need to add the webview to the detailView in the storyboard

Page 28: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

detailViewController.h#import <UIKit/UIKit.h>

@interface CMPDetailViewController : UIViewController <UISplitViewControllerDelegate>

@property (strong, nonatomic) id detailItem;

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

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

@end

Page 29: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

detailViewController.m− (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]; }}

Page 30: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

detailViewController.m− (void)splitViewController:(UISplitViewController *)splitController

willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem

forPopoverController:(UIPopoverController *)popoverController{ barButtonItem.title = NSLocalizedString(@"Master", @"Master"); barButtonItem.title = NSLocalizedString(@"Presidents", @"Presidents"); [self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES]; self.masterPopoverController = popoverController;}

Page 31: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

Storyboard changes

Go to the storyboard in IB

Find the detail view

Move the label to the top of the view

Change the label to “Select a President”

Get a webview out of the library, make it fill the rest of the space in the detail view

Constrain it left and right and bottom

Page 32: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

storyboard

Page 33: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

Storyboard

Control-drag from the Detail View Controller icon (in the Detail View Controller − Detail section in the dock, just below the First Responder icon)

to the web view

Choose the webView outlet in the pop-up box

See next slide

Go to the tableView and change the title to Presidents

Page 34: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

storyboard

Outlet view webView

Choose webView

Page 35: Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use

Run!