1. Trang chủ >
  2. Công Nghệ Thông Tin >
  3. Kỹ thuật lập trình >

3€ Picking Values with UIPickerView

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (3.67 MB, 89 trang )


Figure 2-9. A picker view on top of the screen



As you can see, this specific picker view has 2 components. One is on the left and one

is on the right. The left component is displaying hours (such as 0 hours, 1, 2, etc) and

the component on the right is displaying minutes such as (18, 19, 20 mins, 21, 22, etc).

So these two items (one on the left and the other on the right) are called components.

Each component has rows. Any item in any of the components is in fact repreented by

a row, as we will soon see. For instance, 0 hours, 1 and 2 are, each and all, rows in the

left component.

Let's go ahead and create a picker view on our view controller's view. If you don't know

where your view controller's source code is, please have a look at the Recipe 2.2 recipe

where this subject is discussed.

First let's go to the .h (header) fileof our view controller and define our picker view:

#import

@interface Picking_Values_with_UIPickerViewViewController

: UIViewController



2.3 Picking Values with UIPickerView | 127



@property (nonatomic, strong) UIPickerView *myPicker;

@end



Then we will synthesize it in the .m (implementation) file of our view controller:

#import "Picking_Values_with_UIPickerViewViewController.h"

@implementation Picking_Values_with_UIPickerViewViewController

@synthesize myPicker;

...



Now let's go ahead and create the picker view in the viewDidLoad method of our view

controller:

- (void)viewDidLoad{

[super viewDidLoad];

self.view.backgroundColor = [UIColor whiteColor];

self.myPicker = [[UIPickerView alloc] init];

self.myPicker.center = self.view.center;

[self.view addSubview:self.myPicker];

}



It's worth noting that in this example, we are centering our picker view at the center of

our view so when you run this app, you will see soemthing similar to that shown in

Figure 2-10:



128 | Chapter 2: Implementing Controllers and Views



Figure 2-10. An unpopulated and empty picker with its default black color



The reason this picker view is showing up as plain black color is that we have not yet

populated with any value. Let's do that. We do that by specifying a data source for the

picker view and then making sure that our view controller sticks to the protocol that

the data source requires. The data source of an instance of UIPickerView must conform

to the UIPickerViewDataSource protocol, so, let's go ahead and make our view controller

conform to this protocol, in the .h file:

#import

@interface Picking_Values_with_UIPickerViewViewController



2.3 Picking Values with UIPickerView | 129



: UIViewController

@property (nonatomic, strong) UIPickerView *myPicker;

@end



Good. Let's now change our code in the implementation file to make sure we elect the

current view controller as the data source of the picker view:

- (void)viewDidLoad{

[super viewDidLoad];

self.view.backgroundColor = [UIColor whiteColor];

self.myPicker = [[UIPickerView alloc] init];

self.myPicker.dataSource = self;

self.myPicker.center = self.view.center;

[self.view addSubview:self.myPicker];

}



After this, if you try to compile your application, you will see that you are getting

warnings from the compiler. These warnings are telling you that you have not yet implemented some of the methods which the UIPickerViewDataSource protocol wants you

to implement. The way to fix this is to go back to our .h (header) file, hold down the

Command key and then click on the UIPickerViewDataSource text. At this moment, you

will be sent to where this protocol is defined, where you will see something similar to

this:

@protocol UIPickerViewDataSource

@required

// returns the number of 'columns' to display.

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;

// returns the # of rows in each component..

- (NSInteger)pickerView:(UIPickerView *)pickerView

numberOfRowsInComponent:(NSInteger)component;

@end



Can you see the @required keyword there? That is telling us that whichever class wants

to become the data source of a picker view must implement these methods. Good deal.

Let's go implement them in our view controller's implementation file:

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{

NSInteger result = 0;

if ([pickerView isEqual:self.myPicker]){

result = 1;

}

return result;

}

- (NSInteger)



pickerView:(UIPickerView *)pickerView



130 | Chapter 2: Implementing Controllers and Views



numberOfRowsInComponent:(NSInteger)component{

NSInteger result = 0;

if ([pickerView isEqual:self.myPicker]){

result = 10;

}

return result;

}



So what is happening here? Let's have a look at what each one of these data source

methods expect:

numberOfComponentsInPickerView:



This method passes you a picker view object as its parameter and expect you to

return an integer, telling the runtime how many components you would like that

picker view to render.

pickerView:numberOfRowsInComponent:



For each component that gets added to a picker view, you will need to tell the

system about the number of rows that you would like to render in that component.

This method passes you an instance of picker view and you will need to return an

integer to it, telling the runtime how many rows you want the system to render for

that component.

So in this case, we are asking the system to display 1 component with 10 rows only for

a picker view which we have created before, called myPicker.

Compile and run your application on the iPhone Simulator. Ewww, what is that?



2.3 Picking Values with UIPickerView | 131



Figure 2-11. A picker view, not knowing what to render



It looks like our picker view knows how many components it should have and how

many rows it should render in that component but what it doesn't know is what text

to display for each row. That is something we need to do now and we do that by

providing a delegate to the picker view. The delegate of an instance of UIPickerView

has to conform to the UIPickerViewDelegate protocol and implement all the

@required methods of that protocol. Let's start with our view controller's header file:

@interface Picking_Values_with_UIPickerViewViewController

: UIViewController





132 | Chapter 2: Implementing Controllers and Views



@property (nonatomic, strong) UIPickerView *myPicker;

@end



There is only one method in the UIPickerViewDelegate which we are interested in and

that is the pickerView:titleForRow:forComponent: method. This method will pass you

the index of the current section and the index of the current row in that section for a

picker view and it expects you to return an instance of NSString. This string will then

get rendered for that specific row inside the component. In here, I would simply like

to display the first row as Row 1, and then continue to Row 2, Row 3 till the end.

Remember, we also have to set the delegate property of our picker view:

self.myPicker.delegate = self;



And now we will handle the delegate method which we just learned about:

- (NSString *)pickerView:(UIPickerView *)pickerView

titleForRow:(NSInteger)row

forComponent:(NSInteger)component{

NSString *result = nil;

if ([pickerView isEqual:self.myPicker]){

/* Row is zero-based and we want the first row (with index 0)

to be rendered as Row 1 so we have to +1 every row index */

result = [NSString stringWithFormat:@"Row %ld", (long)row + 1];

}

return result;

}



Now let's run our app and see what happens:



2.3 Picking Values with UIPickerView | 133



Figure 2-12. A picker view with one section and a few rows



All good? If you now refer back to Figure 2-9 you will notice a horizontal bar running

across the picker view. It turns out UIPickerView has a property called showsSelectio

nIndicator which by default is set to NO. You can either directly set the value of this

property to YES or use the setShowsSelectionIndicator: method of the picker view to

turn this indicator on:

self.myPicker.showsSelectionIndicator = YES;



And now we will run our app in iOS Simulator and see how it is looking:

134 | Chapter 2: Implementing Controllers and Views



Figure 2-13. A picker view with selection indicator



Now imagine that you have create this picker view in your final application. What is

the use of a picker view if we cannot detect what the user has actually selected in each

one of its components? Well, it's good that Apple has already thought of that and given

us the ability to ask the picker view about this. We can call the selectedRowInCompo

nent: method of a UIPickerView and pass the zero-based index of a component to get

an integer back and this integer will be the zero-based index of the row which is currently selected in that component.



2.3 Picking Values with UIPickerView | 135



If at runtime, you need to modify the values in your picker view, you need to make sure

that your picker view reloads its data from its data source and delegate. To do that, you

can either force all the components to reload their data, using the reloadAllCompo

nents or you can ask a specific component to reload its data, using the reloadCompo

nent: method and passing the index of the component that has to be reloaded.



See Also

XXX



2.4 Picking Date and Time with UIDatePicker

Problem

You want to allow the users of your app to select date and time using an intuitive and

read-made user interface



Solution

Use the UIDatePicker class.



Discussion

The UIDatePicker is very similar to the UIPickerView class. The date picker is in fact a

pre-populated picker view. A good example of the date picker control is in the Calendar

app on the iPhone:



136 | Chapter 2: Implementing Controllers and Views



Figure 2-14. A date picker shown at the bottom of the screen



Let's get started by first declaring a property of type UIDatePicker and then allocating

and initializing this property and adding it to the view of our view controller:

#import

@interface Picking_Date_and_Time_with_UIDatePickerViewController

: UIViewController

@property (nonatomic, strong) UIDatePicker *myDatePicker;

@end



Let's synthesize the property now:

#import "Picking_Date_and_Time_with_UIDatePickerViewController.h"

@implementation Picking_Date_and_Time_with_UIDatePickerViewController

@synthesize myDatePicker;



2.4 Picking Date and Time with UIDatePicker | 137



Xem Thêm
Tải bản đầy đủ (.pdf) (89 trang)

×