web-dev-qa-db-ja.com

iOS 7.1 UITapGestureがUIPickerViewで機能しない

UIPickerViewを使用して、ユーザーがオプションのリストから選択できるようにしています。コンテナUIViewのサブビューとしてUIPickerViewを追加しています。次に、UITapGestureRecognizerをコンテナUIViewに追加します。 UITapGestureRecognizerは、スーパービューを削除してピッカーを閉じるために使用されています。

IOS 7.0以前のバージョンでは、これは期待どおりに機能していました。ただし、iOS 7.1では、UITapGestureRecognizerがタップを認識せず、アクションで指定されたセレクターを呼び出す(ピッカービューとコンテナービューを閉じる)という意味で、このセットアップは機能しなくなりました。コードは以下です

   - (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.nameList=[[NSMutableArray alloc] initWithObjects:@"A",@"B",@"C", nil];
    UIPickerView *myPickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 200, 320, 200)];
    myPickerView.delegate = self;
    myPickerView.showsSelectionIndicator = YES;
    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapInListPickerView:)];
    [singleTap setNumberOfTapsRequired:1];
    [singleTap setNumberOfTouchesRequired:1];
    [myPickerView addGestureRecognizer:singleTap];
    [self.view addSubview:myPickerView];
}

-(void)tapInListPickerView:(UIGestureRecognizer *)sender

{
    NSLog(@"Taped in pikcer view");
}

他の情報が必要な場合、またはこれを行うためのより好ましい方法がある場合は、お知らせください。

35
Anupam

私は同じ問題を抱えていて、ついに啓示を受けました:P

それは、uiPickerViewの同時ジェスチャーレンコグナイザが機能しないようでした。

ジェスチャーデリゲートを使用します

<
UIGestureRecognizerDelegate>

 // add tap gesture
    UITapGestureRecognizer* gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(pickerViewTapGestureRecognized:)];
    [picker addGestureRecognizer:gestureRecognizer];
    gestureRecognizer.delegate = self;

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
    // return
    return true;
}

そしてその働き!

またね

87
ZDidier

ほぼ UIPickerViewをサブクラス化して元の機能を復元し、hitTest実装をオーバーライドできました。新しい実装では、最初にピッカーのすべての行がタッチイベントを要求できるようにしてから、最後にピッカー自体がそれを要求できるようにします。

私はほぼと言います。ピッカーに表示されているビューがもう存在しない可能性があるUIPickerViewに別の変更があるためです。そのため、ユーザーはピッカーの中央に配置されていない行の可視画像をタップすると、実際には存在しないため、その行を選択する代わりにピッカーがスクロールすることがあります。

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    if (self.hidden) {
        return nil;
    }
    else {
        if (event.type == UIEventTypeTouches) {
            for (int component = 0; component < self.numberOfComponents; component++) {
                for (int row = 0; row < [self numberOfRowsInComponent:component]; row++) {
                    UIView *view = [self viewForRow:row forComponent:0];
                    if (view) {
                        view = [view hitTest:[self convertPoint:point toView:view] withEvent:event];
                        if (view) {
                            return view;
                        }
                    }
                }
            }
        }
        return [super hitTest:point withEvent:event];
    }
}
2
Doug Gerecht

受け入れられた答えは非常に役に立ちます、ありがとう!私はすでにUIPickerViewをサブクラス化していました。そこで、ZDidierに続いて、サブクラスをUIGestureRecognizerDelegateにし、addGestureRecognizerを次のようにオーバーライドしました。

- (void)addGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
{
    gestureRecognizer.delegate = self;
    [super addGestureRecognizer:gestureRecognizer];
}

それで解決しました。

1
John

レイジーのためのスウィフトメソッド:

プロトコルに準拠UIGestureRecognizerDelegate

そして

override func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}
0