UIPickerViewでクリックされた行を特定する

問題


最近、アプリケーションのインターフェイスをUIPickerView要素で装飾することにしましたが、標準のツールセット、つまり、目的の要素が「選択インジケータ」の下にあるようにスクロールして、何らかのアクションを実行することはできませんでした。 任意の行をクリックすることにより、必要なパラメーターを含むメッセージが送信されるようにする必要がありました。 そのため、UITapGestureRecogniserをねじ込んでUIPickerViewをカスタマイズすることにしました。



解決策


以下に、アクションの順序をステップごとに書き留めます。 UIPickerViewDelegateおよびUIPickerViewDataSourceプロトコルを宣言するUIViewControllerのサブクラスを使用します。



  1. UITapGestureRecogniserをUIPickerViewに追加します。



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







    viewDidLoad:関数でこのアクションを実行しました。 whereAreYouTappedOnPicker:-これは、ピッカーがクリックされたときに呼び出され、クリックされた行を計算するセレクターです。



  2. UIViewControllerのサブクラスのヘッダー(.hファイル)でwhereAreYouTappedOnPicker:を宣言します。



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



  3. 以前に発表した関数の実装を記述します(これは.mファイルで行います)。



     -(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]; } }
          
          







    次に、ユーザーがピッカーをスクロールするときと、ユーザーが目的の行をクリックするときの2つのケースを提供する必要があります。 didSelectRow:はコードを使用したスクロールに応答しないため、これが必要です。ここでは、「異なる関数」が必要です。



    したがって、2つのイベントがあります。

    1. ユーザーがピッカーをスクロールすると、didSelectRow:メソッドが呼び出され、customPickerView:メソッドが呼び出され、「選択インジケーター」の下にある行のインデックスがパラメーターとして渡されます。
    2. ユーザーが目的の行をクリックすると、whereAreYouTappedOnPicker:メソッドが呼び出されます。このメソッドでは、customPickerView:メソッドが呼び出され、押された行のインデックスがパラメーターとして渡されます。


    DidSelectRowメソッドのコード:



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







  4. customPickerView関数をヘッダーで宣言します。



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







  5. customPickerView関数の実装を.mファイルに記述します。



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







問題


ピッカーをすばやくクリックすると、selectedRowが-1になることがあります。 行をクリックすると、新しいビューに切り替えますので、このオプションが適しています。



All Articles