Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 89 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
89
Dung lượng
5,03 MB
Nội dung
@synthesize window = _window; @synthesize rootViewController; 3. Now find the application:didFinishLaunchingWithOptions: method of the app delegate, inside the implementation (.m) file, and instantiate the view controller and add it to our window: - (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; [self.window makeKeyAndVisible]; self.rootViewController = [[RootViewController alloc] initWithNibName:nil bundle:NULL]; [self.window addSubview:self.rootViewController.view]; return YES; } We add the view of the view controller to the window, not the view controller itself. Now if you run your app on the simulator, you will see a black screen. The reason is that our view controller's view doesn't have a background color yet so go to the Root- ViewController.m file and find the viewDidLoad method which is in a state similar to this: /* - (void)viewDidLoad { [super viewDidLoad]; } */ Remove the comment lines from around this method: - (void)viewDidLoad{ [super viewDidLoad]; } Now let's set the background color of our view controller's view to white: - (void)viewDidLoad{ [super viewDidLoad]; 162 | Chapter 2: Implementing Controllers and Views self.view.backgroundColor = [UIColor whiteColor]; } Go ahead and run the app on the simulator. You will now see a plain white view on the screen. Congratulations, you just created a view controller and now you have access to the view controller and its view object. While creating the view controller (Figure 2-26), if you had selected the With XIB for user interface checkbox, then Xcode would have also generated an .xib file for you. In such case, we would have to load our view controller from that .xib file by passing the .xib file's full name to the initWithNibName parameter of the initWithNibName:bun dle: method of the view controller, like so: - (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; [self.window makeKeyAndVisible]; self.rootViewController = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:NULL]; [self.window addSubview:self.rootViewController.view]; return YES; } If you did create a .xib file while creating your view controller, you can now select on that file in Xcode and design your user interface with Interface Builder. See Also XXX 2.8 Implementing Navigation with UINavigationController Problem You would like to allow your users to move from one view controller to the other with a smooth and built-in animation. Solution Use UINavigationController. 2.8 Implementing Navigation with UINavigationController | 163 Discussion If you've used an iPhone, iPod Touch or an iPad before, chances are that you have already seen a navigation controller in action. For instance, if you go to the Settings app on your phone and then press an option such as Wallpaper (Figure 2-28), you will see the Settings' main screen get pulled out of the screen from the left and the Wallpaper screen pushing its way into the screen from the right. That is the magic of navigation controllers. They allow you to push and pop view controllers, where pushing a view controller means pushing it into the stack of view controllers and popping a view con- troller means removing that view controller from the stack. The view controller on top of the stack is the top view controller and that is the view controller which the user sees at any given moment. So we can conclude that only the top view controller gets dis- played to the user unless that view controller is popped or another view controller is pushed onto the stack in which case the new view controller becomes the top view controller and the one getting displayed to the user. Figure 2-28. Settings view controller pushing the Wallpaper view controller 164 | Chapter 2: Implementing Controllers and Views Now we are going to add a navigation controller to our project but we need a project first. Please follow the instructions in Recipe 2.7 to create an empty application with a simple view controller. In this recipe we will expand on the recipe in Recipe 2.7. Let's start with the .h file of our app delegate: #import <UIKit/UIKit.h> @class RootViewController; @interface Implementing_Navigation_with_UINavigationControllerAppDelegate : UIResponder <UIApplicationDelegate> @property (nonatomic, strong) UIWindow *window; @property (nonatomic, strong) UINavigationController *navigationController; @property (nonatomic, strong) RootViewController *rootViewController; @end And then we need to make sure we have synthesized our navigation controller's prop- erty: #import "Implementing_Navigation_with_UINavigationControllerAppDelegate.h" #import "RootViewController.h" @implementation Implementing_Navigation_with_UINavigationControllerAppDelegate @synthesize window = _window; @synthesize navigationController; @synthesize rootViewController; Now we have to initialize our navigation controller using its initWithRootViewControl ler: method and pass our root view controller as its parameter. Then we will add the navigation controller's view to the window: - (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; [self.window makeKeyAndVisible]; self.rootViewController = [[RootViewController alloc] initWithNibName:nil bundle:NULL]; self.navigationController = [[UINavigationController alloc] initWithRootViewController:self.rootViewController]; [self.window addSubview:self.navigationController.view]; 2.8 Implementing Navigation with UINavigationController | 165 return YES; } Now let's run our app in the simulator: Figure 2-29. An empty view controller displayed inside a navigation controller The first thing you might notice in Figure 2-29 is the bar on top of the screen. The screen isn't plain white anymore. There is a bar on top. What is that, you might ask? Well, that is a navigation bar. We will be using that bar alot for navigation, placing buttons there and etc. That bar is also capable of displaying a title. Each view controller specifies a title for itself and the navigation controller will automatically display that 166 | Chapter 2: Implementing Controllers and Views title once the view controller is pushed into the stack. Let's go to our root view con- troller's implementation file and inside the viewDidLoad method set the title property of our view controller to First Controller: - (void)viewDidLoad{ [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; self.title = @"First Controller"; } Run the app again and you will see something similar to that shown in Figure 2-30: Figure 2-30. A view controller with title 2.8 Implementing Navigation with UINavigationController | 167 Now let's go and create a second view controller, without a .xib file, and call it Second ViewController. Follow the same process that you learnt in Recipe 2.7. Once you are done creating this view controller, give it a title of Second Controller. #import "SecondViewController.h" @implementation SecondViewController - (void)viewDidLoad{ [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; self.title = @"Second Controller"; } Our plan is to push the second view controller on top of the first view controller 5 seconds after the first view controller appears on the screen so let's first import the second view controller in the first one: #import "RootViewController.h" #import "SecondViewController.h" @implementation RootViewController Now go back to the implementation of the root view controller and code the viewDi dAppear: like this: - (void) pushSecondController{ SecondViewController *secondController = [[SecondViewController alloc] initWithNibName:nil bundle:NULL]; [self.navigationController pushViewController:secondController animated:YES]; } - (void) viewDidAppear:(BOOL)paramAnimated{ [super viewDidAppear:paramAnimated]; [self performSelector:@selector(pushSecondController) withObject:nil afterDelay:5.0f]; } We are using the performSelector:withObject:afterDelay: method of NSObject to call our new method pushSecondController 5 seconds after our first view controller suc- cessfully displays its view. In the pushSecondController method we are simply using the navigationController property of our view controller (this is built into UIViewControl ler and is not something that we coded) to push an instance of SecondViewController into the stack of view controllers. The result? Similar to what you can see in Figure 2-31. 168 | Chapter 2: Implementing Controllers and Views Figure 2-31. A view controller is pushed on top of another one You can see that the navigation bar is displaying the title of the top view controller and it even displays a back button which will take the user back to the previous view con- troller. You can push as many view controllers as you would like into the stack and the navigation controller will work the navigation bar to display the relevant back buttons which allow the user to back through your application's UI, all the way to the first screen. We learnt about pushing a view controller. How about popping or removing a view controller from the stack of the navigation controller? The answer is straightforward: 2.8 Implementing Navigation with UINavigationController | 169 using the popViewControllerAnimated: method of the navigation controller. Let's make our second view controller pop itself off of the stack automatically 5 seconds after it is displayed on the screen: - (void) goBack{ [self.navigationController popViewControllerAnimated:YES]; } - (void) viewDidAppear:(BOOL)paramAnimated{ [super viewDidAppear:paramAnimated]; [self performSelector:@selector(goBack) withObject:nil afterDelay:5.0f]; } So if you open the app in the simulator now and wait 5 seconds after the first view controller is displayed, you will see that the second view controller will automatically get displayed on the screen. Wait another 5 seconds now and the second view controller will automatically go back to the first view controller. See Also XXX 2.9 Manipulating a Navigation Controller’s Array of View Controllers Problem You would like to directly manipulate the array of view controllers associated with a specific navigation controller. Solution Use the viewControllers property of the UINavigationController class to access and modify the array of view controllers associated with a navigation controller: - (void) goBack{ /* Get the current array of View Controllers */ NSArray *currentControllers = self.navigationController.viewControllers; /* Create a mutable array out of this array */ NSMutableArray *newControllers = [NSMutableArray arrayWithArray:currentControllers]; /* Remove the last object from the array */ [newControllers removeLastObject]; /* Assign this array to the Navigation Controller */ 170 | Chapter 2: Implementing Controllers and Views self.navigationController.viewControllers = newControllers } You can call this method inside any view controller in order to pop the last view con- troller from the hierarchy of the navigation controller associated with the current view controller. Discussion An instance of the UINavigationController class holds an array of UIViewController objects. After retrieving this array, you can manipulate it in any way that you wish. For instance, you can remove a view controller from an arbitrary place in the array. Manipulating the view controllers of a navigation controller directly by assigning an array to the viewControllers property of the navigation controller will commit the op- eration without a transition/animation. If you wish this operation to be animated, use the setViewControllers:animated: method of the UINavigationController class, as shown in the following snippet: - (void) goBack{ /* Get the current array of View Controllers */ NSArray *currentControllers = self.navigationController.viewControllers; /* Create a mutable array out of this array */ NSMutableArray *newControllers = [NSMutableArray arrayWithArray:currentControllers]; /* Remove the last object from the array */ [newControllers removeLastObject]; /* Assign this array to the Navigation Controller with animation */ [self.navigationController setViewControllers:newControllers animated:YES]; } See Also XXX 2.10 Displaying an Image on a Navigation Bar Problem You want to display an image instead of text as the title of the current view controller on the navigation controller. Solution Use the titleView property of the view controller’s navigation item: 2.10 Displaying an Image on a Navigation Bar | 171 [...]... CGRectMake(0.0f, 0.0f, 100.0f, 23. 0f); self.myLabel = [[UILabel alloc] initWithFrame:labelFrame]; self.myLabel.text = @ "iOS 5 Programming Cookbook" ; self.myLabel.font = [UIFont boldSystemFontOfSize:14.0f]; self.myLabel.center = self.view.center; [self.view addSubview:self.myLabel]; } Now let's run our app and see what happens: 2. 13 Displaying Static Text with UILabel | 1 93 Figure 2-42 A label that is... runs out of horizontal space If you set this value to 3, it tells the label that you want the text to wrap to three lines if it cannot fit the text into one line: self.myLabel.numberOfLines = 3; If you run the app now, you will get the desired results: Figure 2- 43 A label wrapping its contents to 3 lines 2. 13 Displaying Static Text with UILabel | 1 95 In some situations, you might not know how many lines... our app now, we will see something similar to this: 174 | Chapter 2: Implementing Controllers and Views Figure 2 -33 A navigation button added to a navigation bar That was simple and easy But if you are an iOS user, you probably have noticed that the system apps that come preconfigured on iOS have a different Add button Have you noticed that? Here is an example in the Alarm section of the Clock app on... 23. 0f as we say in Figure 2-42, we could adjust the font of the label to fit into the boundaries Here is how it works: - (void)viewDidLoad{ [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; CGRect labelFrame = CGRectMake(0.0f, 0.0f, 100.0f, 23. 0f); self.myLabel = [[UILabel alloc] initWithFrame:labelFrame]; self.myLabel.adjustsFontSizeToFitWidth = YES; self.myLabel.text = @ "iOS 5. .. One solution would be to make the width longer but how about the height? What if we wanted the text to wrap to the next line? Ok, go ahead and change the height from 23. 0f to 50 .0f: CGRect labelFrame = CGRectMake(0.0f, 0.0f, 100.0f, 50 .0f); 194 | Chapter 2: Implementing Controllers and Views If you run your app now, you will get exactly the same results that you got in Figure 2-42 But you might ask,... Alarm section of the Clock app on the IPhone Notice the + button on the top right of the navigation bar: 2.11 Adding Buttons to Navigation Bars with UIBarButtonItem | 1 75 Figure 2 -34 The proper way of creating an Add button It turns out, iOS SDK allows us to create system buttons on the navigation bar We do that by using the initWithBarButtonSystemItem:target:action: initializer of the UIBar ButtonItem... an example: Figure 2 -32 Different buttons displayed on a navigation bar You might be surprised that the bar on the bottom of Figure 2 -32 is also a navigation bar! Navigation bars are of class UINavigationBar and can be created at any time and added to any view So just look at all the different buttons with different shapes which have been added to the navigation bars in Figure 2 -32 The ones on the top... (void)viewDidLoad{ [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; } Now let's run our app and see what happens: Figure 2 -38 A very simple tab bar populated with two view controllers 2.12 Presenting Multiple View Controllers with UITabBarController | 1 85 You can see that our view controllers do not have a navigation bar What should we do? It's easy Remember that a UINavigationController... addSubview:self.tabBarController.view]; return YES; } And the results? Exactly what we wanted: 2.12 Presenting Multiple View Controllers with UITabBarController | 187 Figure 2 -39 A tab bar displaying view controllers inside navigation controllers As we can see in Figure 2 -34 , each tab bar item can have text and an image We've learnt the using the title property of a view controller, we can specify this text but what about... items with images See Also XXX 190 | Chapter 2: Implementing Controllers and Views 2. 13 Displaying Static Text with UILabel Problem You want to display static text to your users You would also like to control using which font and color the text is rendered Solution Use the UILabel class Discussion Labels are everywhere in iOS You can practically see them in every application, except for games where the . Views Figure 2 -33 . A navigation button added to a navigation bar That was simple and easy. But if you are an iOS user, you probably have noticed that the system apps that come preconfigured on iOS have. bar: 2.11 Adding Buttons to Navigation Bars with UIBarButtonItem | 1 75 Figure 2 -34 . The proper way of creating an Add button It turns out, iOS SDK allows us to create system buttons on the navigation. controllers. The result? Similar to what you can see in Figure 2 -31 . 168 | Chapter 2: Implementing Controllers and Views Figure 2 -31 . A view controller is pushed on top of another one You can see