Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "Navigation in iPads splitViewController. Overview Create a Master-Detail application Switch Device Family to iPad Give the project a name and click “Use."— Presentation transcript:

1 Navigation in iPads splitViewController

2 Overview Create a Master-Detail application Switch 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

3 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.

4 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

5 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

6 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.

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

8 Testing Run.

9 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)

10 CMPAppDelegate.h #import @interface CMPAppDelegate : UIResponder @property (strong, nonatomic) UIWindow *window; @end Nothing new here.

11 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 controller The 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.

12 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.

13 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.

14 CMPDetailViewController.h #import @interface CMPDetailViewController : UIViewController @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.

15 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.

16 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.

17 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)

18 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

19 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

20 plist presidents name George Washington url http://en.wikipedia.org/wiki/George_Washington

21 masterViewController.h #import @class CMPDetailViewController; @interface CMPMasterViewController : UITableViewController @property (strong, nonatomic) CMPDetailViewController *detailViewController; @property (copy, nonatomic) NSArray *presidents; @end Add this property to store the information.

22 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.

23 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

24 masterViewController.m Change 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.

25 masterViewController.m Change 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.

26 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

27 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

28 detailViewController.h #import @interface CMPDetailViewController : UIViewController @property (strong, nonatomic) id detailItem; @property (weak, nonatomic) IBOutlet UILabel *detailDescriptionLabel; @property (weak, nonatomic) IBOutlet UIWebView *webView; @end

29 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]; }

30 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; }

31 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

32 storyboard

33 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

34 storyboard Outlet view webView Outlet view webView Choose webView

35 Run!


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

Similar presentations


Ads by Google