SO、ジェスチャー認識機能をオーバーレイビューに追加しています。画面をタップすると、このオーバーレイが消えます。ジェスチャレコグナイザーを追加すると、「内部修正」およびその他のボタンクリックイベントがオーバーライドされると述べました。私はこれを必要とするので、ジェスチャ認識を削除する必要があります。この方法は使用できますが、問題があります。以下の私のコード-
- (void)helpClicked
{
CGRect visibleBounds = [self convertRect:[self bounds] toView:viewContainer];
CGFloat minimumVisibleX = CGRectGetMinX(visibleBounds);
UIImageView * helpOverlay = [[UIImageView alloc]initWithFrame:CGRectMake(minimumVisibleX, 0, 1024, 768)];
UIImage * helpImage = [UIImage imageNamed:@"HelpOverLay.png"];
[helpOverlay setImage:helpImage];
helpOverlay.tag = 50;
self.scrollEnabled = NO;
[self addSubview:helpOverlay];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(dismissView)];
[self addGestureRecognizer:tap];
}
ここで、他のビューからオーバーレイを取ります。
- (void) dismissView
{
UIView *overlay = [self viewWithTag:50];
[overlay removeFromSuperview];
self.scrollEnabled = YES;
}
私の質問は、2番目の方法でジェスチャー認識機能を削除するにはどうすればよいですか?変数tapをこのメソッドに渡すことも、前のメソッドで変数tapを削除することもできません。ポインタはありますか?私は、イベントに関しては非常に多くの通過変数の問題に悩まされてきました。
WWDC 2015、Cocoa Touch Best Practices から、後でアクセスする必要がある場合はプロパティまたはiVarを保持し、viewWithTag:
。
これにより、トラブルからあなたを救います:
(つまり)タグで初めて実装しましたが、すべてが期待どおりに機能します。後で、別の機能に取り組みます。これにより、これを破り、予期しない望ましくない動作を引き起こすことができます。ログは警告を表示しませんが、場合によってはインスタンスに送信されるクラッシュシグナル認識されないセレクターに応じて取得できる最良のもの。 これらのいずれも取得できない場合があります。
IVarを宣言する
@implementation YourController {
UITapGestureRecognizer *tap;
}
ビューを設定する
- (void) helpClicked {
//Your customization code
//Adding tap gesture
tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissView)];
[self addGestureRecognizer:tap];
}
ジェスチャーを直接削除する
- (void) dismissView {
[self.view removeGestureRecognizer:tap];
}
このループは、ビューにあるすべてのジェスチャー認識機能を削除します
for (UIGestureRecognizer *recognizer in self.view.gestureRecognizers) {
[self.view removeGestureRecognizer:recognizer];
}
ivar
UITapGestureRecognizer *tap
あなたの@interface
。
helpClicked
を次のように変更します。
- (void)helpClicked
{
CGRect visibleBounds = [self convertRect:[self bounds] toView:viewContainer];
CGFloat minimumVisibleX = CGRectGetMinX(visibleBounds);
UIImageView * helpOverlay = [[UIImageView alloc]initWithFrame:CGRectMake(minimumVisibleX, 0, 1024, 768)];
UIImage * helpImage = [UIImage imageNamed:@"HelpOverLay.png"];
[helpOverlay setImage:helpImage];
helpOverlay.tag = 50;
self.scrollEnabled = NO;
[self addSubview:helpOverlay];
tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(dismissView)];
[self addGestureRecognizer:tap];
}
およびdismissView
へ:
for (UIGestureRecognizer *recognizer in self.view.gestureRecognizers) {
[self removeGestureRecognizer:tap];
}
編集:nhahtdhの方法はこれに比べて少しエレガントだと思います。
EDIT2:[self addGestureRecognizer:tap]
動作しているので、これはUIView
のサブクラスであると想定しています。
Swiftバージョン:
if let recognizers = yourView.gestureRecognizers {
for recognizer in recognizers {
yourView.removeGestureRecognizer(recognizer)
}
}
ジェスチャレコグナイザをセットアップして、オーバーレイビューを一度セットアップするだけで、オーバーレイビューをhiddenにします。ビューが非表示の場合、ユーザーからのタッチは一切受けません。オーバーレイビューを必要な場合にのみ表示し、必要でない場合は非表示にします。
2番目の方法では、コードはおそらく次のようになります。
- (void) dismissView {
UIView *overlay = [self viewWithTag:50];
for (UIGestureRecognizer *recognizer in self.view.gestureRecognizers) {
if([recognizer isKindOfClass:[UITapGestureRecognizer class]]) {
[self removeGestureRecognizer:recognizer];
}
}
[overlay removeFromSuperview];
self.scrollEnabled = YES;
}
クラスが複数のUITapGestureRecognizer
sを処理し、それだけを削除したい場合に備えて、UIGestureRecognizer
のチェックを追加しました。
私のためのこの仕事:
for (UIGestureRecognizer *gr in self.view.gestureRecognizers) {
[self.view removeGestureRecognizer:gr];
}
In Swift 4
if let gestures = shotButton.gestureRecognizers //first be safe if gestures are there
{
for gesture in gestures //get one by one
{
shotButton.removeGestureRecognizer(gesture) //remove gesture one by one
}
}
ビューを拡張できる場合は、次の方法を試すことができます。
_ = gestureRecognizers.flatMap { $0.map { removeGestureRecognizer($0) } }
それは私のために働いた。
while (view.gestureRecognizers.count) {
[view removeGestureRecognizer:[view.gestureRecognizers objectAtIndex:0]];
}