beginning iphone 3 development exploring the iphone sdk phần 4 pps

58 541 0
beginning iphone 3 development exploring the iphone sdk phần 4 pps

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

CHAPTER 7: Tab Bars and Pickers148 Delegates and Datasources Before we dive in and start building our application, let’s look at why pickers are so much more complex than the other controls you’ve used so far. It’s not just a matter of there being more configurable attributes to set in Interface Builder. In fact, the picker actually has very few attributes that can be configured from within Interface Builder. With the exception of the date picker, you can’t use a picker by just grabbing one in Interface Builder, dropping it on your content view, and configuring it. You have to also provide it with both a picker del- egate and a picker datasource. By this point, you should be comfortable using delegates. We’ve already used application delegates and action sheet delegates, and the basic idea is the same here. The picker defers several jobs to its delegate. The most important of these is the task of determining what to actually draw for each of the rows in each of its components. The picker asks the delegate for either a string or a view that will be drawn at a given spot on a given component. The picker gets its data from the delegate. In addition to the delegate, pickers need to have a datasource. In this instance, the name “datasource” is a bit of a misnomer. The datasource tells the picker how many components it will be working with and how many rows make up each component. The datasource works similarly to the delegate, in that its methods are called at certain, prespecified times. Without a datasource and a delegate specified, pickers cannot do their job and, in fact, won’t even be drawn. It’s very common for the datasource and the delegate to be the same object, and just as common for that object to be the view controller for the picker’s enclosing view, which is the approach we’ll be using in this application. The view controllers for each content pane will be the datasource and the delegate for their picker. NOTE Here’s a pop quiz: is the picker datasource part of the model, view, or controller portion of the application? It’s a trick question. A datasource sounds like it must be part of the model, but in fact, it’s actually part of the controller. The datasource isn’t usually an object designed to hold data. Though in simple applications the datasource might hold data, its true job is to retrieve data from the model and pass it along to the picker. Let’s fire up Xcode and get to it. 24594ch07.indd 148 6/23/09 11:28:59 AM Download at Boykma.Com CHAPTER 7: Tab Bars and Pickers 149 Setting Up the Tab Bar Framework Although Xcode does provide a template for tab bar applications, we’re going to build ours from scratch. It’s not much extra work, and it’s good practice. So, create a new project, select- ing the Window-based Application template again. When prompted for a name, type Pickers, and make sure the checkbox that says Use Core Data for storage is unchecked. We’re going to walk you through the process of building the whole application, but if, at any step of the way, you feel like challenging yourself by moving ahead of us, by all means, go ahead. If you get stumped, you can always come back. If you don’t feel like skipping ahead, that’s just fine. We’d love the company. Creating the Files In the previous chapter, we created a root controller to manage the process of swapping our application’s other views. We’ll be doing that again this time, but we won’t need to create our own root controller class. Apple provides a very good class for managing tab bar views, so we’re just going to use an instance of UITabBarController as our root controller. We will create that instance in Interface Builder in a few minutes. First, we need to create five new classes in Xcode: the five view controllers that the root con- troller will swap in and out. Expand the Classes and Resources folders in the Groups & Files pane. Next, single-click the Classes folder, and press ⌘N or select New File… from the File menu. Select Cocoa Touch Classes in the left pane of the new file assistant, and then select the icon for UIViewController subclass. In the bottom-right pane, just above the descrip- tion of the selected template, you should see a checkbox labeled With XIB for user interface (Figure 7-7). Make sure that’s checked before clicking Next. Name the first one DatePickerViewController.m, making sure to check Also create “DatePickerViewController.h”. After you click the Finish button, there will be three new files in your Classes folder: DatePickerViewController.h, DatePickerViewController.m, and DatePickerViewController.xib. The nib file doesn’t belong in the Classes folder, so drag DatePickerViewController.xib down to the Resources folder. Repeat those steps four more times, using the names SingleComponentPickerViewController.m, DoubleComponentPickerViewController.m, DependentComponentPickerViewController.m, and CustomPickerViewController.m. 24594ch07.indd 149 6/23/09 11:28:59 AM Download at Boykma.Com CHAPTER 7: Tab Bars and Pickers150 Figure 7-7. When creating a subclass of UIViewController, Xcode will create the accompanying XIB file for you if you select “With XIB for user interface”. Adding the Root View Controller We’re going to create our root view controller, which will be an instance of UITabBarController, in Interface Builder. Before we can do that, however, we should declare an outlet for it. Single-click the PickersAppDelegate.h class, and add the following code to it: #import <UIKit/UIKit.h> @interface PickersAppDelegate : NSObject <UIApplicationDelegate> { UIWindow *window; UITabBarController *rootController; } @property (nonatomic, retain) IBOutlet UIWindow *window; @property (nonatomic, retain) IBOutlet UITabBarController *rootController; @end Before we move to Interface Builder to create our root view controller, let’s add the following code to PickersAppDelegate.m: #import "PickersAppDelegate.h" @implementation PickersAppDelegate 24594ch07.indd 150 6/23/09 11:29:00 AM Download at Boykma.Com CHAPTER 7: Tab Bars and Pickers 151 @synthesize window; @synthesize rootController; - (void)applicationDidFinishLaunching:(UIApplication *)application { // Override point for customization after app launch [window addSubview:rootController.view]; [window makeKeyAndVisible]; } - (void)dealloc { [rootController release]; [window release]; [super dealloc]; } @end There shouldn’t be anything in this code that’s a surprise to you. This is pretty much the same thing we did in the previous chapter, except that we’re using a controller class pro- vided by Apple this time instead of one we wrote ourselves. Make sure you save both files before continuing. Tab bars use icons to represent each of the tabs, so we should also add the icons we’re going to use before heading over to Interface Builder. You can find some suitable icons in the proj- ect archive that accompanies this book in the 07 Pickers/Tab Bar Icons/ folder. The icons should be 24 by 24 pixels and saved in .png format. The icon file should have a transparent background. Generally, medium gray icons look the best on a tab bar. Don’t worry about try- ing to match the appearance of the tab bar. Just as it does with the application icon, the iPhone is going to take your image and make it look just right. You should be comfortable adding resources to your project by this point, so go ahead and add the five icons we’ve provided by dragging them from the Finder to the Resources folder of your Xcode project or selecting Add to Project. . . from the Project menu. Once you’ve added the icons, double-click MainWindow.xib to open the file in Interface Builder. Drag a Tab Bar Controller from the library (see Figure 7-8) over to the nib’s main window. Be sure you drag to the window labeled MainWindow.xib and not to the window labeled Window, which will not accept the drag, so you’ll know when you get it right. Figure 7-8. Tab Bar Controller in the library 24594ch07.indd 151 6/23/09 11:29:00 AM Download at Boykma.Com CHAPTER 7: Tab Bars and Pickers152 Once you drop the tab bar controller onto your nib’s main window, a new window will appear that looks like Figure 7-9. This tab bar controller will be our root controller. As a reminder, the root controller controls the very first view that the user will see when your program runs. Single-click the Tab Bar Controller icon in your nib’s main window, and press ⌘1 to bring up the attributes inspector for it. The attributes inspector for a tab bar controller will look like Figure 7-10. The part that we’re interested in is the top section, which is labeled View Controllers. When all is said and done, we’ll end up with one view controller for each of our tab controller’s tabs. Take a look back at Figure 7-2. As you can see, our program features five tabs, one for each of our five subviews—five subviews, five view controllers. Turn your attention back to the attributes inspector for the tab bar controller. We need to change our tab bar controller so it has five tabs instead of two. Click the button with the plus sign on it three times to create a total of five controllers. The attributes inspector will show five items, and if you look over at the Tab Bar Controller window, you’ll see that it now has five buttons instead of two. Figure 7-9. The tab bar controller’s window Figure 7-10. The attributes inspector for the tab bar controller 24594ch07.indd 152 6/23/09 11:29:00 AM Download at Boykma.Com CHAPTER 7: Tab Bars and Pickers 153 Click the tab bar at the bottom of the Tab Bar Controller window. Be sure you click the leftmost tab. This should select the controller that corresponds to the leftmost tab, and the inspector should change to look like Fig- ure 7-11. If your inspector doesn’t look like Figure 7-11, click the second tab and then back on the first tab. Here’s where we associate each tab’s view controller with the appropriate nib. This leftmost tab will launch the first of our five subviews. Leave the Title field blank. Tab bar controllers don’t use this title for anything, though some other kinds of view control- lers do. The checkbox labeled Wants Full Screen can be used to indicate that the view that comes up when you press that tab will overlap and hide the tabs bar. If you check this checkbox, you must provide an alternative mechanism for navigating off that tab. We will leave this value unchecked for all of our tabs. Finally, specify a NIB Name of DatePickerView- Controller. Do not include the .xib extension. Leave the Resize View From NIB checkbox checked. This won’t apply to us, since we’ll design our views to not need resizing. While you are here, press ⌘4. This will bring up the identity inspector for the view controller associated with the leftmost tab. Change the class to DatePicker- ViewController, and press return or tab to set it. Press ⌘1 to return to the attributes inspector. Click the first tab in the tab bar, and click it again in the same spot. This should cause the inspector to change again, so it looks like Figure 7-12. By clicking the tab bar again in the same spot, we’ve changed the selection from the view controller associ- ated with the tab bar item to the tab bar item itself. In other words, the first click selected the first of the five subview’s view controllers. The second click selects the tab bar item itself so that we can set its title and icon. The first item on the Tab Bar Item inspector is labeled Badge. This can be used to put a red icon onto a tab bar item, similar to the red number placed on the Mail icon that tells you how many unread e-mails you have. We’re not going to use the badge field in this chapter, so you can leave it blank, but we thought you’d want to know what it does. Under that, there’s a pop-up button called Identifier. This field allows you to select from a set of commonly used tab bar item names and icons such as Favorites and Search. If you select one of these, then it will provide the name and icon for the item based on your selection. We’re not using standard items, so you can ignore this one for now also. Figure 7-11. The view controller attributes inspector Figure 7-12. The tab bar item attri- butes inspector 24594ch07.indd 153 6/23/09 11:29:00 AM Download at Boykma.Com CHAPTER 7: Tab Bars and Pickers154 The next two fields down are where we can specify a title and custom tab icon for a tab bar item. Change the Title from Item 1 to Date, click the Image combo box, and select the clockicon.png image. If you are using your own set of icons, select one of the .png files you provided instead. For the rest of this chapter, we’ll discuss the resources we provided. Make adjustments for your own media, as necessary. If you look over at the Tab Bar Controller window, you’ll see that the leftmost tab bar item now reads Date and has a picture of a clock on it. We now need to repeat this process for the other four tab bar items. Before we do, let’s revisit what we just did. First, we single-clicked the first tab and used the attributes inspector to specify the nib name for that first tab’s associated view controller. Next, we opened the identity inspector and changed the underlying class of the view con- troller associated with this tab. We then clicked the tab again to edit the tab bar item, instead of the view controller. We gave the tab bar item a title and an icon. Let’s repeat this for the next four view controller/tab bar item pairings. Click the second tab, and bring up the attributes inspector. Change the second view control- ler’s nib name to SingleComponentPickerViewController. Switch to the identity inspector, and change the view controller’s class to SingleComponentPickerViewController. Click the second tab again, and return to the attributes inspector. Give the second tab bar item a title of Sin- gle, and specify an Image of singleicon.png. Click the third tab, and bring up the attributes inspector. Change the third view controller’s nib name to DoubleComponentPickerViewController. Switch to the identity inspector, and change the view controller’s class to DoubleComponentPickerViewController. Click the third tab again, and return to the attributes inspector. Give the third tab bar item a title of Double, and specify an Image of doubleicon.png. Click the fourth tab, and bring up the attributes inspector. Change the fourth view control- ler’s nib name to DependentComponentPickerViewController. Switch to the identity inspector, and change the view controller’s class to DependentComponentPickerViewController. Click the fourth tab again, and return to the attributes inspector. Give the fourth tab bar item a title of Dependent, and specify an Image of dependenticon.png. Click the fifth tab, and bring up the attributes inspector. Change the fifth view controller’s nib name to SinglePickerViewController. Switch to the identity inspector, and change the view controller’s class to CustomPickerViewController. Click the fifth tab again, and return to the attributes inspector. Give the fifth tab bar item a title of Custom, and specify an Image of toolicon.png. 24594ch07.indd 154 6/23/09 11:29:00 AM Download at Boykma.Com CHAPTER 7: Tab Bars and Pickers 155 NOTE Don’t worry about the view controller Title fields. We don’t use them. They can be blank or not. We do use the tab bar item Title fields. Don’t confuse the two. All that we have left to do in this nib file is to control-drag from the Pickers App Delegate icon to the Tab Bar Controller icon, selecting the rootController outlet. Save your nib, and go back to Xcode. At this point, the tab bar and the content views should all be hooked up and working. Com- pile and run, and your application should launch with a toolbar that functions; clicking a tab should select it. There’s nothing in the content views now, so the changes won’t be very dramatic. But if everything went OK, the basic framework for your multiview application is now set up and working, and we can start designing the individual content views. TIP If your simulator bursts into flames when you click one of the tabs, don’t panic! Most likely, you’ve either missed a step or made a typo. Go back and check all the nib file names, make sure the connections are right, and make sure the class names are all set correctly. If you want to make double sure everything is working, you can add a different label or some other object to each of the content views and then relaunch the application. If everything is working, you’ll see the content of the different views change as you select different tabs. Implementing the Date Picker To implement the date picker, we’ll need a single outlet and a single action. The outlet will be used to grab the value from the date picker. The action will be triggered by a but- ton and will throw up an alert to show the date value pulled from the picker. Single-click DatePickerViewController.h, and add the following code: 24594ch07.indd 155 6/23/09 11:29:00 AM Download at Boykma.Com CHAPTER 7: Tab Bars and Pickers156 #import <UIKit/UIKit.h> @interface DatePickerViewController : UIViewController { UIDatePicker *datePicker; } @property (nonatomic, retain) IBOutlet UIDatePicker *datePicker; -(IBAction)buttonPressed; @end Save this file, and double-click DatePickerViewController.xib to open the content view for this first tab in Interface Builder. The first thing we need is to size the view correctly for the space available. The easiest way to do that is to single-click the View icon and press ⌘1 to bring up the attributes inspector. We can use the Simulated Interface Elements to have Interface Builder size this view correctly by setting the Bottom Bar popup to Tab Bar. This will cause Interface Builder to automatically reduce the view’s height to 411 pixels and show a simu- lated tab bar. Next, we need to add a date picker to this view, so look for Date Picker in the library (see Figure 7-13), and drag one over to the View window. If the View window is not open, open it by double-clicking the View icon in the nib’s main window. Place the date picker right at the top of the view. It should take up the entire width of your content view and a good portion of the height. Don’t use the blue guidelines for the picker; it’s designed to fit snugly against the edges of the view (see Figure 7-14). Single-click the date picker if it’s not already selected, and press ⌘1 to bring up the attri- butes inspector. As you can see (in Figure 7-15), a number of attributes can be configured for a date picker. You won’t get off this easy with the rest of the pickers, so enjoy it while you can. We’re going to leave most of the values at their defaults, though you should feel free to play with the options when we’re done to see what they do. The one thing we are going to do is limit the range of the picker to reasonable dates. Look for the heading that says Constraints, and check the box that reads Minimum Date. Leave the Minimum date value at the default of 1/1/1970. Also check the box that reads Maximum Date, and set Maximum to 12/31/2200. Next, grab a Round Rect Button from the library, and place it below the date picker. Double- click it, and give it a title of Select, and press ⌘2 to switch to the connections inspector. Drag from the circle next to the Touch Up Inside event over to the File’s Owner icon, and connect to the buttonPressed action. Then control-drag from the File’s Owner icon back to the date picker, and select the datePicker outlet. Save, close the nib, and go back to Xcode. Figure 7-13. The Date Picker in the library 24594ch07.indd 156 6/23/09 11:29:00 AM Download at Boykma.Com CHAPTER 7: Tab Bars and Pickers 157 Figure 7-14. Place all pickers right up against the edges of the view, either at the top or bottom of the view. Figure 7-15. The attributes inspector for a date picker Now we just need to implement DatePickerViewController, so click DatePickerViewController.m, and first, add the following code at the top of the file: #import "DatePickerViewController.h" @implementation DatePickerViewController @synthesize datePicker; -(IBAction)buttonPressed { NSDate *selected = [datePicker date]; NSString *message = [[NSString alloc] initWithFormat: @"The date and time you selected is: %@", selected]; 24594ch07.indd 157 6/23/09 11:29:01 AM Download at Boykma.Com [...]... selection changes If the value on the left changes, we will grab the correct array out of the dictionary and assign it to the array being used for the right-hand component Don’t worry if you didn’t catch all that; we’ll talk about it more as we get into the code Download at Boykma.Com 245 94ch07.indd 170 6/ 23/ 09 11:29: 04 AM CHAPTER 7:  Tab Bars and Pickers NSArray 1 2 34 5 1 2 34 6 1 2 34 7 1 2 34 8 NSDictionary Alabama... Arizona Arkansas 171 NSArray NSArray NSArray NSArray NSArray 1 235 4 1 235 6 1 235 7 1 235 8 NSArray 1 2 34 5 1 2 34 6 1 2 34 7 1 2 34 8 Figure 7-17 Our application’s data: for each state there will be one entry in a dictionary with the name of the state as the key Stored under that key will be an NSArray instance containing all the ZIP codes from that state Add the following code to your DependentComponentPickerViewController.h... any time the picker’s selection changes, we look at the component and see whether the left-hand component changed If it did, we grab the array that corresponds to the new selection and assign it to the zips array Then we set the right-hand component back to the first row and tell it to reload itself By swapping the zips array whenever the state changes, the rest of the code remains pretty much the same... the implementation of this controller Add the following code at the beginning of CustomPickerViewController.m file: #import "CustomPickerViewController.h" @implementation CustomPickerViewController @synthesize picker; @synthesize winLabel; @synthesize column1; Download at Boykma.Com 245 94ch07.indd 179 6/ 23/ 09 11:29:05 AM 180 CHAPTER 7:  Tab Bars and Pickers @synthesize @synthesize @synthesize @synthesize... picker and one component, we don’t bother with either of the arguments and simply return the count of objects from our sole data array Download at Boykma.Com 245 94ch07.indd 1 64 6/ 23/ 09 11:29: 03 AM CHAPTER 7:  Tab Bars and Pickers 165 After the two datasource methods, we implement one delegate method Unlike the datasource methods, all of the delegate methods are optional The term “optional” is a bit deceiving... Figure 7 -4 Notice that each wheel is completely independent of the other one Turning one has no effect on the other That’s appropriate in this case But there are going to be times when one component is dependent on another A good example of this is in the date picker When you change the month, the dial that shows the number of days in the month may have to change because not all months have the same... text displayed until the first time the user wins After that, make all the connections to outlets and actions You need to connect the file’s owner’s picker outlet to the picker view, the file’s owner’s winLabel outlet to the label, and the button’s touch up inside event to the spin action After that, just make sure to specify the Delegate and the DataSource for the picker Oh, and there’s one additional... work with other compilers or in other environments If the compiler doesn’t recognize the directive, it ignores it, though it may generate a warning In this case, the #pragma directives are actually directives to the IDE, not the compiler, and they tell Xcode’s editor to put a break in the pop-up menu of methods and functions at the top of the editor pane, as shown in the following screen shot The first... to the previous section if you need a step-by-step guide, since the two applications are identical in terms of the nib file Here’s a summary of what you need to do: 1 Connect the doublePicker outlet on File’s Owner to the picker 2 Connect the DataSource and Delegate connections on the picker view to File’s Owner (use the connections inspector) 3 Connect the Touch Up Inside event of the button to the. .. CustomPickerViewController.xib to open the file in Interface Builder Set the Simulated Interface Elements to simulate a tab bar at the bottom of the view, and then add a label, a picker, and a button Give the button a title of Spin Next, select the label and use the resize handles to increase the size so that it takes up the width from left margin to right margin, and most of the available height left between the button and . 7-10. The attributes inspector for the tab bar controller 245 94ch07.indd 152 6/ 23/ 09 11:29:00 AM Download at Boykma.Com CHAPTER 7: Tab Bars and Pickers 1 53 Click the tab bar at the bottom of the. and one component, we don’t bother with either of the arguments and simply return the count of objects from our sole data array. 245 94ch07.indd 1 64 6/ 23/ 09 11:29: 03 AM Download at Boykma.Com CHAPTER. the View window. If the View window is not open, open it by double-clicking the View icon in the nib’s main window. Place the date picker right at the top of the view. It should take up the

Ngày đăng: 09/08/2014, 14:20

Từ khóa liên quan

Mục lục

  • Tab Bars and Pickers

    • Delegates and Datasources

    • Setting Up the Tab Bar Framework

      • Creating the Files

      • Adding the Root View Controller

      • Implementing the Date Picker

      • Implementing the Single Component Picker

        • Declaring Outlets and Actions

        • Building the View

        • Implementing the Controller as Datasource and Delegate

        • Implementing a Multicomponent Picker

          • Declaring Outlets and Actions

          • Building the View

          • Implementing the Controller

          • Implementing Dependent Components

          • Creating a Simple Game with a Custom Picker

            • Writing the Controller Header File

            • Building the View

            • Adding Image Resources

            • Implementing the Controller

            • The spin Method

            • The viewDidLoad Method

            • Final Details

            • Linking in the Audio Toolbox Framework

            • Final Spin

Tài liệu cùng người dùng

Tài liệu liên quan