1 / 35

Navigation in iPads

Navigation in iPads. splitViewController. 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.

dane
Download Presentation

Navigation in iPads

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

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 splitViewController Nav controller for left side Table view for left side (in landscape mode) 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. View for right side Nav controller for right side

  4. Organization You don’t see this code You cannot just push views on the right side; must maintain the delegate relationship. SplitViewController You can push new views on the left side Left side Nav controller Right side Nav controller delegate You can add subviews to the right side without destroying the delegate relationship. Left side View (table) (masterViewController) Right side View (detailViewController)

  5. Organization SplitViewController Left side Nav controller self.splitViewController 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.navigationController Left side View (table) (masterViewController)

  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 Nothing new here. #import <UIKit/UIKit.h> @interface CMPAppDelegate : UIResponder <UIApplicationDelegate> @property (strong, nonatomic) UIWindow *window; @end

  11. 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. 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.viewControllerslastObject]; 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.

  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 = [[UIBarButtonItemalloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAddtarget:self action:@selector(insertNewObject:)]; self.navigationItem.rightBarButtonItem = addButton; self.detailViewController= (CMPDetailViewController *) [[self.splitViewController.viewControllerslastObject] topViewController]; } We’re adding an edit button to the navigation bar. Now add an insert button. self.splitViewController.viewControllerslastObject is the navigation controller for the detail view. The top controller for the navController is the CMPDetailViewController

  14. CMPDetailViewController.h #import <UIKit/UIKit.h> @interface CMPDetailViewController : UIViewController <UISplitViewControllerDelegate> @property (strong, nonatomic) id detailItem; @property (weak, nonatomic) IBOutletUILabel *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, configureViewbecomes 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.masterPopoverControllerdismissPopoverAnimated: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 These are splitViewController delegate methods. − (void)splitViewController:(UISplitViewController *)splitControllerwillHideViewController: (UIViewController *)viewControllerwithBarButtonItem:(UIBarButtonItem *) barButtonItemforPopoverController:(UIPopoverController *)popoverController { barButtonItem.title = NSLocalizedString(@"Master", @"Master"); [self.navigationItemsetLeftBarButtonItem:barButtonItemanimated:YES]; self.masterPopoverController = popoverController; } − (void)splitViewController:(UISplitViewController *)splitControllerwillShowViewController: (UIViewController *)viewControllerinvalidatingBarButtonItem:(UIBarButtonItem *) barButtonItem { // Called when the view is shown again in the split view, invalidating the button and popover controller. [self.navigationItemsetLeftBarButtonItem:nilanimated:YES]; self.masterPopoverController = nil; } 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 See • 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

  19. Plist • First download the file PresidentList.plistfrom 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 PresidentListplist 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 <?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>

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

  22. masterViewController.m - (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.leftBarButtonItem = self.editButtonItem; NSString *path = [[NSBundlemainBundle] pathForResource:@"PresidentList" ofType:@"plist"]; NSDictionary *presidentInfo = [NSDictionarydictionaryWithContentsOfFile:path]; self.presidents = [presidentInfoobjectForKey:@"presidents"]; UIBarButtonItem *addButton = [[UIBarButtonItemalloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAddtarget:self action:@selector(insertNewObject:)]; self.navigationItem.rightBarButtonItem = addButton; self.detailViewController = (CMPDetailViewController *) [[self.splitViewController.viewControllerslastObject] 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 *)tableViewnumberOfRowsInSection:(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 *)tableViewcellForRowAtIndexPath:(NSIndexPath *) indexPath { UITableViewCell *cell = [tableViewdequeueReusableCellWithIdentifier:@"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 *)tableViewdidSelectRowAtIndexPath:(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 *)tableViewcanEditRowAtIndexPath:(NSIndexPath *)indexPath − (void)tableView:(UITableView *)tableViewcommitEditingStyle: (UITableViewCellEditingStyle)editingStyleforRowAtIndexPath:(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 <UIKit/UIKit.h> @interface CMPDetailViewController : UIViewController <UISplitViewControllerDelegate> @property (strong, nonatomic) id detailItem; @property (weak, nonatomic) IBOutletUILabel*detailDescriptionLabel; @property (weak, nonatomic) IBOutletUIWebView *webView; @end

  29. detailViewController.m − (void)configureView { // Update the user interface for the detail item. NSURL *url = [NSURL URLWithString:self.detailItem]; NSURLRequest *request = [NSURLRequestrequestWithURL:url]; [self.webViewloadRequest:request]; if (self.detailItem) { self.detailDescriptionLabel.text = [self.detailItem description]; } }

  30. detailViewController.m − (void)splitViewController:(UISplitViewController *)splitControllerwillHideViewController:(UIViewController *)viewControllerwithBarButtonItem:(UIBarButtonItem *)barButtonItemforPopoverController:(UIPopoverController *)popoverController { barButtonItem.title = NSLocalizedString(@"Master", @"Master"); barButtonItem.title= NSLocalizedString(@"Presidents", @"Presidents"); [self.navigationItemsetLeftBarButtonItem:barButtonItemanimated: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 Choose webView Outlet view webView

  35. Run!

More Related