📜 ⬆️ ⬇️

Determine which row was clicked in UIPickerView

Problem

Recently I decided to pre-paint the interface of my application with the UIPickerView element, but I was not completely satisfied with what the standard set of tools offered me, namely: scroll it so that the desired element becomes under “Selection Indicator” and then perform some action. I needed to send a message with the necessary parameters by clicking on any line. So I decided to customize UIPickerView by attaching a UITapGestureRecogniser to it.

Decision

Below I will describe step by step the order of my actions. I work with the UIViewController subclass in which the UIPickerViewDelegate and UIPickerViewDataSource protocols are declared.

  1. Add UITapGestureRecogniser to UIPickerView:

    UITapGestureRecognizer *tapgesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(whereAreYouTappedOnPicker:)]; [self.pickerView addGestureRecognizer:tapgesture]; 

    ')
    This action is performed in the viewDidLoad: function. whereAreYouTappedOnPicker: is the selector that will be called when you click on the picker and calculate which line was pressed.

  2. We declare whereAreYouTappedOnPicker: in the header (.h file) of your UIViewController subclass.

    - (void) whereAreYouTappedOnPicker: (UIGestureRecognizer *) gestureRecognizer;

  3. We write the implementation of the function that we declared earlier (we do it in the .m file).

     -(void)whereAreYouTappedOnPicker:(UIGestureRecognizer *)gestureRecognizer { //     UIPickerView CGPoint tapCoordinate = [gestureRecognizer locationInView:self.pickerView]; //    UIPickerView.    5          CGFloat heightOfPickerRow = self.pickerView.frame.size.height/5; //          NSInteger rowForSelectionIndicator =[self.pickerView selectedRowInComponent:0]; //           "Selection Indicator" if (tapCoordinate.y<heightOfPickerRow) { //         //        if ([self.pickerView selectedRowInComponent:0] > 1) rowForSelectionIndicator -=2; else rowForSelectionIndicator = -1; //    } else if (tapCoordinate.y<2*heightOfPickerRow) { //         //        if ([self.pickerView selectedRowInComponent:0] > 0) rowForSelectionIndicator -=1; else rowForSelectionIndicator = -1; //    } else if (tapCoordinate.y<3*heightOfPickerRow) { //        ,      "Selection Indicator" //  ,       rowForSelectionIndicator = [self.pickerView selectedRowInComponent:0]; } else if (tapCoordinate.y<4*heightOfPickerRow) { //         //        if ([self.pickerView selectedRowInComponent:0] < ([self.pickerView numberOfRowsInComponent:0]-1)) rowForSelectionIndicator +=1; else rowForSelectionIndicator = -1; //    } else { //         //        if ([self.pickerView selectedRowInComponent:0] < ([self.pickerView numberOfRowsInComponent:0]-2)) rowForSelectionIndicator += 2; else rowForSelectionIndicator = -1; //    } //     -       if (rowForSelectionIndicator!=-1) { //      // -  didSelectRow            . [self.pickerView selectRow:rowForSelectionIndicator inComponent:0 animated:YES]; //     [self customPickerView:self.pickerView didSelectRow:rowForSelectionIndicator inComponent:0 asResultOfTap:YES]; } } 


    Next, we need to provide for two cases: when the user scrolls the picker and when the user clicks on the desired line. We need this then, that didSelectRow: does not respond to scrolling with the help of the code, here we need the “other function”

    And so, we will have two events:
    1. When the user scrolls the piker, the didSelectRow method is called: in which the customPickerView: method is called and the index of the row that is under the “Selection Indicator” is passed as a parameter.
    2. When the user clicks on the desired line, the whereAreYouTappedOnPicker method is called: in which the customPickerView: method is called and the index of the line that was clicked is passed as a parameter.

    Method code didSelectRow:

     - (void)pickerView:(UIPickerView *)pickerView didSelectRow: (NSInteger)row inComponent:(NSInteger)component { [self customPickerView:pickerView didSelectRow:row inComponent:component asResultOfTap:NO]; } 


  4. We declare the customPickerView: function in the header.

     -(void)customPickerView:(UIPickerView *)pickerView didSelectRow: (NSInteger)row inComponent:(NSInteger)component asResultOfTap:(bool)userTapped; 


  5. Writing the implementation of the customPickerView function: in the .m file

     - (void)customPickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component asResultOfTap:(bool)userTapped { if (userTapped) //       { NSLog(@"  %i", row); } else //       "Selection Indicator"   { NSLog(@" %i", row); } } 


Problems

Sometimes when you quickly click on the picker selectedRow becomes equal to -1. When I click on the line, I move to the new View, so this option suits me.

Source: https://habr.com/ru/post/142796/


All Articles