UI -- UIPickerView and UIDatePicker summary, uidatepicker

Source: Internet
Author: User
Tags switch case

UI -- UIPickerView and UIDatePicker summary, uidatepicker

The main method for returning to the top UIPickerView and the correction of the city Selector

UIPickerView has only two data source methods. To completely display the PickerView, you must use the proxy data source method:

// The total number of columns-(NSInteger) numberOfComponentsInPickerView :( UIPickerView *) pickerView // The number of rows in each column. The input parameter component is the corresponding column-(NSInteger) pickerView :( UIPickerView *) pickerView numberOfRowsInComponent :( NSInteger) component

Proxy method of UIPickerView:

// Tell the system what data is displayed in each row. Generally, the-(NSString *) pickerView (UIPickerView *) pickerView titleForRow :( NSInteger) row forComponent :( NSInteger) component can be used in combination with the switch case; // listen to the pickerView Click Event-(void) pickerView :( UIPickerView *) pickerView didSelectRow :( NSInteger) row inComponent :( NSInteger) component;

Some other common methods

// PickerView object method, select the specified row in the specified column-(void) selectRow :( NSInteger) row inComponent :( NSInteger) component animated :( BOOL) animated // object method, gets the row number of the currently selected row in the specified column. If no row is selected,-1-(NSInteger) selectedRowInComponent :( NSInteger) component is returned;

When the province and city are modified in the city selection program at the same time, the cause and Modification Scheme of the program crash will be:

The most common problem in this project is that each selector continuously calls the following two methods during the change process.
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
In the two methods, use the following method to obtain the currently selected items:
- (NSInteger)selectedRowInComponent:
The value returned by this method is changed. Therefore, if you calculate the index of the selected item of com1 based on this value, the array may be out of bounds. Therefore, my solution is to use the value of the member variable. Each didSelected operation changes the fixed value after a fixed value.

1. First, add the member attribute selectedRowOfComp1 of the class.

2. Calculate the number of columns in the second column, that is, the "city" column, based on the first row selected by the member attribute storage. InpickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)componentMedium

if (component == 0) {    return self.provinces.count;}MKProvince *p = self.provinces[self.selectedRowOfComp1];return p.cities.count;
The method for displaying data in each row has also been changed:
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{    if (component == 0) {        MKProvince *p = self.provinces[row];        return p.name;    } else {        MKProvince *p = self.provinces[self.selectedRowOfComp1];        return p.cities[row];    }}

3. After selecting the province data, modify the member attributes and refresh the city data. The cities and provinces to be displayed in the label are also calculated based on the member attribute values:

-(Void) pickerView :( UIPickerView *) pickerView didSelectRow :( NSInteger) row inComponent :( NSInteger) component {if (component = 0) {MKProvince * p = self. provinces [row]; // change the display self of lbl. lblProvince. text = p. name; // change the display self of the city group. selectedRowOfComp1 = row; [pickerView reloadComponent: 1]; // This sentence must be in self. selectedRowOfComp1 = row. ReloadComponent: 1 reload component1 but it does not change the selected row number. Therefore, the selected row may be the second line, if the province becomes Chongqing, only one city may cause bugs, but no, in this case, reload will display the city data as the first line // update the lblCity data NSInteger cityIndex = [pickerView selectedRowInComponent: 1]; self. lblCity. text = p. cities [cityIndex]; // the previous sentence updates component1, which ensures data consistency between lbl and component1} else {MKProvince * p = self. provinces [self. selectedRowOfComp1]; // change the display self of lbl. lblCity. text = p. cities [row] ;}}
Return to the use of UIDatePicker on the top and extract it as a Tool class.

Create a UIDatePicker

// First create dataPickerCGFloat width = [UIScreen mainScreen]. bounds. size. width; UIDatePicker * datePicker = [[UIDatePicker alloc] initWithFrame: CGRectMake (0, 0, width, 180)]; datePicker. locale = [NSLocale localeWithLocaleIdentifier: @ "zh-Hans"]; // set the default region datePicker. datePickerMode = UIDatePickerModeDate; // set the input mode to date self. datePicker = datePicker; // set it as the controller's snapshot self.txt Time. inputView = self. datePicker; // set datePicker as the input of the textField control // viewUIToolbar * toolbar = [[UIToolbar alloc] initWithFrame: CGRectMake (0, 0, width, 44)]; UIBarButtonItem * item1 = [[UIBarButtonItem alloc] initWithTitle: @ "last" style: UIBarButtonItemStylePlain target: self action: @ selector (previous)]; UIBarButtonItem * item2 = [[UIBarButtonItem alloc] initWithTitle: @ "next" style: UIBarButtonItemStylePlain target: self action: @ selector (next)]; UIBarButtonItem * item3 = [[UIBarButtonItem alloc] lower: lower target: nil action: nil]; UIBarButtonItem * item4 = [[UIBarButtonItem alloc] initWithTitle: @ "finish" style: lower target: self action: @ selector (done)]; // toolbar of the listener event. items = @ [item1, item2, item3, item4]; self.txt Time. inputAccessoryView = toolbar; // sets toolbar as an affiliated view of the textField input.

Process the done Button clicking event after the input is complete

-(Void) done {[self. view endEditing: YES]; // format the selected date NSDate * date = self. datePicker. date; NSDateFormatter * fmt = [[NSDateFormatter alloc] init]; fmt. dateFormat = @ "MM dd, yyyy"; NSString * dateStr = [fmt stringFromDate: date]; // assign the formatted string to textField self.txt Time. text = dateStr ;}
Extraction as tool class

Create a tool class MKToolDatePicker in MKToolDatePicker. h.

# Import "MKTool. h "@ class UITextField; @ protocol MKToolDatePickerDelegate;/*** this class must be strongly referenced after creation */@ interface MKToolDatePicker: MKTool/*** specifies the UITextField control to be set */@ property (nonatomic, weak) id delegate;-(void) datePickerOnTextField :( UITextField *) textField; @ end @ protocol MKToolDatePickerDelegate/*** is called when the "finish" button of the time selector is clicked and the proxy class (usually the Controller) has implemented this method, used to process the selected NSDate ** @ param toolDatePicker tool class object itself * @ param textField specified textField * @ param date click the date selected before "completion" */-(void) toolDatePicker :( MKToolDatePicker *) toolDatePicker onView :( UITextField *) textField didClickedDoneWithDate :( NSDate *) date; @ end

In MKToolDatePicker. m

# Import "MKToolDatePicker. h "# import <UIKit/UIDatePicker. h> # import <UIKit/UIScreen. h> # import <UIKit/UIToolbar. h> @ interface MKToolDatePicker () @ property (nonatomic, strong) UIDatePicker * datePicker; @ property (nonatomic, strong) UIToolbar * toolBar; @ property (nonatomic, weak) UITextField * textField; @ end @ implementation MKToolDatePicker-(UIDatePicker *) datePicker {if (! _ DatePicker) {// create dataPicker CGFloat width = [UIScreen mainScreen] first. bounds. size. width; _ datePicker = [[UIDatePicker alloc] initWithFrame: CGRectMake (0, 0, width, 180)]; _ datePicker. locale = [NSLocale localeWithLocaleIdentifier: @ "zh-Hans"]; _ datePicker. datePickerMode = UIDatePickerModeDate;} return _ datePicker;}-(UIToolbar *) toolBar {if (! _ ToolBar) {// The attached view _ toolBar = [[UIToolbar alloc] initWithFrame: CGRectMake (0, 0, [UIScreen mainScreen]. bounds. size. width, 44)]; UIBarButtonItem * item1 = [[UIBarButtonItem alloc] initWithTitle: @ "last" style: UIBarButtonItemStylePlain target: self action: @ selector (previous)]; UIBarButtonItem * item2 = [[UIBarButtonItem alloc] initWithTitle: @ "next" style: UIBarButtonItemStylePlain target: self action: @ selector (next)]; UIBarButtonItem * item3 = [[UIBarButtonItem alloc] lower: lower target: nil action: nil]; UIBarButtonItem * item4 = [[UIBarButtonItem alloc] initWithTitle: @ "finish" style: lower target: self action: @ selector (done)]; _ toolBar. items = @ [item1, item2, item3, item4];} return _ toolBar;}-(void) datePickerOnTextField :( UITextField *) textField {self. textField = textField; textField. inputView = self. datePicker; textField. inputAccessoryView = self. toolBar;}-(void) done {[self. textField endEditing: YES]; if ([self. delegate respondsToSelector: @ selector (toolDatePicker: onView: didClickedDoneWithDate :)]) {[self. delegate toolDatePicker: self onView: self. textField didClickedDoneWithDate: self. datePicker. date] ;}}

Use the time selector tool class in the Controller

# Import "ViewController. h "# import" MKToolDatePicker. h "@ interface ViewController () @ property (weak, nonatomic) IBOutlet UITextField * txtTime; // strongly referenced time selector tool @ property (nonatomic, strong) MKToolDatePicker * toolDatePicker; @ end @ implementation ViewController-(void) viewDidLoad {[super viewDidLoad]; MKToolDatePicker * tool = [[MKToolDatePicker alloc] init]; self. toolDatePicker = tool; tool. delegate = self; // set the proxy [tool datePickerOnTextField: self.txt Time]; // specify UITextView} // process them separately based on onView-(void) toolDatePicker :( MKToolDatePicker *) toolDatePicker onView :( UITextField *) textField didClickedDoneWithDate :( NSDate *) date {NSDateFormatter * fmt = [[NSDateFormatter alloc] init]; fmt. dateFormat = @ "MM dd, yyyy"; NSString * dateStr = [fmt stringFromDate: date]; self.txt Time. text = dateStr;} @ end

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.