UITapGestureRecognizer
のビューがあります。そのため、ビューをタップすると、このビューの上に別のビューが表示されます。この新しいビューには3つのボタンがあります。これらのボタンのいずれかを押すと、ボタンアクションが表示されず、タップジェスチャアクションのみが表示されます。そのため、これらのボタンはもう使用できません。これらのボタンにイベントを送信するにはどうすればよいですか?奇妙なことは、ボタンがまだ強調表示されることです。
UITapGestureRecognizerをタップした後に削除することはできません。これにより、新しいビューも削除できるためです。 フルスクリーンビデオコントロールのような動作が必要なことを意味します。
コントローラーまたはビュー(ジェスチャー認識機能を作成する方)をUITapGestureRecognizer
のデリゲートとして設定できます。次に、デリゲートで-gestureRecognizer:shouldReceiveTouch:
を実装できます。実装では、タッチが新しいサブビューに属しているかどうかをテストできます。そうであれば、ジェスチャーレコグナイザーにそれを無視するように指示します。次のようなもの:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
// test if our control subview is on-screen
if (self.controlSubview.superview != nil) {
if ([touch.view isDescendantOfView:self.controlSubview]) {
// we touched our control surface
return NO; // ignore the touch
}
}
return YES; // handle the touch
}
ケヴィン・バラードの答えへのケーシーのフォローアップのフォローアップとして:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if ([touch.view isKindOfClass:[UIControl class]]) {
// we touched a button, slider, or other UIControl
return NO; // ignore the touch
}
return YES; // handle the touch
}
これにより、基本的にボタン、スライダーなどのすべてのユーザー入力タイプのコントロールが機能します。
ここでこの答えを見つけました: link
使用することもできます
tapRecognizer.cancelsTouchesInView = NO;
これにより、タップ認識エンジンがすべてのタップをキャッチする唯一の存在になりません
更新- Michael このプロパティを説明するドキュメントへのリンクに言及しました: cancelsTouchesInView
Kevin Ballardの回答のフォローアップとして、私はこの同じ問題を抱えていて、このコードを使用することになりました。
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if ([touch.view isKindOfClass:[UIButton class]]){
return NO;
}
return YES;
}
同じ効果がありますが、これは任意のビュー深度の任意のUIButtonで機能します(私のUIButtonはいくつかのビューの深さで、UIGestureRecognizerのデリゲートはそれへの参照を持っていませんでした。)
IOS 6.0以降では、デフォルトのコントロールアクションにより、ジェスチャレコグナイザーの動作の重複が防止されます。たとえば、ボタンのデフォルトアクションはシングルタップです。ボタンの親ビューにアタッチされたシングルタップジェスチャレコグナイザーがあり、ユーザーがボタンをタップすると、ボタンのアクションメソッドはジェスチャレコグナイザーの代わりにタッチイベントを受け取ります。これは、コントロールのデフォルトアクションと重複するジェスチャ認識にのみ適用されます。
これらの答えは不完全でした。このブール演算の使用方法については、複数の投稿を読む必要がありました。
* .hファイルにこれを追加します
@interface v1ViewController : UIViewController <UIGestureRecognizerDelegate>
* .mファイルにこれを追加します
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
NSLog(@"went here ...");
if ([touch.view isKindOfClass:[UIControl class]])
{
// we touched a button, slider, or other UIControl
return NO; // ignore the touch
}
return YES; // handle the touch
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//tap gestrure
UITapGestureRecognizer *tapGestRecog = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(screenTappedOnce)];
[tapGestRecog setNumberOfTapsRequired:1];
[self.view addGestureRecognizer:tapGestRecog];
// This line is very important. if You don't add it then your boolean operation will never get called
tapGestRecog.delegate = self;
}
-(IBAction) screenTappedOnce
{
NSLog(@"screenTappedOnce ...");
}
here から別の方法を見つけました。各ボタンの中かどうかに関係なく、タッチを検出します。
(1) pointInside:withEvent: (2) locationInView:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldReceiveTouch:(UITouch *)touch {
// Don't recognize taps in the buttons
return (![self.button1 pointInside:[touch locationInView:self.button1] withEvent:nil] &&
![self.button2 pointInside:[touch locationInView:self.button2] withEvent:nil] &&
![self.button3 pointInside:[touch locationInView:self.button3] withEvent:nil]);
}
リリー・バラードの答え のSwiftバージョンは次のとおりです。
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
if (scrollView.superview != nil) {
if ((touch.view?.isDescendantOfView(scrollView)) != nil) { return false }
}
return true
}
Cdasherの答えを最適化すると、
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldReceiveTouch:(UITouch *)touch
{
return ![touch.view isKindOfClass:[UIControl class]];
}
シンプルなビューと、そのビューにサブビューとして追加されたUIButton、UITextFieldコントロールがあります。ここで、コントロール(追加したサブビュー)以外のビュー上の任意の場所をタッチすると、キーボードを閉じます。
XYZViewController.m(ビューがあります)に次のメソッドを追加します
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}
次のブール値を設定することにより、UITapGestureRecognizerが他のイベント(ボタンのタップなど)をキャンセルしないようにすることができます。
[tapRecognizer setCancelsTouchesInView:NO];