47

複数のサブビューを持つビューがあります。ユーザーがサブビューをタップすると、サブビューのサイズが拡大して画面の大部分をカバーしますが、他のサブビューの一部は引き続き下に表示されます。

サブビューの1つがこのように「拡張」されている場合、アプリが他のサブビューへのタッチを無視するようにします。これを達成する簡単な方法はありますか?これを処理するコードを書くことはできますが、もっと簡単な組み込みの方法があることを望んでいました。

4

12 に答える 12

56

この助けを願っています...

[[yourSuperView subviews]
   makeObjectsPerformSelector:@selector(setUserInteractionEnabled:)
   withObject:[NSNumber numberWithBool:FALSE]];

これにより、ビューの直接のサブビューのuserInteractionが無効になります。次に、必要な唯一のビューにuserInteractionを指定します。

yourTouchableView.setUserInteraction = TRUE;

編集:

iOSでは、親ビューでuserInteractionを無効にしても、その子でuserInteractionが無効にならないようです。したがって、上記のコード(つまり、のコード makeObjectsPerformSelector:は、親の直接のサブビューのuserInteractionを無効にする場合にのみ機能します。

すべてのサブビューを再帰的に取得し、それらすべてのユーザー操作を無効にするユーザーmadewulfの回答を参照してください。または、プロジェクトの多くの場所でこのビューのuserInteractionを無効にする必要がある場合は、UIViewを分類して、その機能を追加できます。

@interface UIView (UserInteractionFeatures)
-(void)setRecursiveUserInteraction:(BOOL)value;
@end

@implementation UIView(UserInteractionFeatures)
-(void)setRecursiveUserInteraction:(BOOL)value{
    self.userInteractionEnabled =   value;
    for (UIView *view in [self subviews]) {
        [view setRecursiveUserInteraction:value];
    }
}
@end

今、あなたは呼び出すことができます

[yourSuperView setRecursiveUserInteraction:NO];

また、すべてのビューの上に非表示のビューを追加するというユーザー@lxtの提案は、それを行うもう1つの方法です。

于 2011-03-23T12:04:09.150 に答える
47

これを行うにはいくつかの方法があります。他のすべてのサブビューを繰り返し処理して設定することもできuserInteractionEnabled = NOますが、他のビューがたくさんある場合、これは理想的とは言えません(結局、それらすべてを後で再利用する必要があります)。

これを行う方法は、すべてのタッチが他のビューに移動するのを「ブロック」する画面全体のサイズの非表示のUIViewを作成することです。これは文字通り見えない場合もあれば、アルファ値が0.3程度の黒に設定する場合もあります。

メインサブビューを展開して画面全体に表示すると、その背後にこの「ブロック」UIViewを追加できます(を使用insertSubview: belowSubview:)。拡張されたサブビューを最小化すると、非表示のUIViewを階層から削除できます。

したがって、完全には組み込まれていませんが、最も単純なアプローチだと思います。それがあなたがすでに考えていたものであったかどうかはわかりませんが、うまくいけば、それはいくつかの助けになりました。

于 2011-03-23T12:01:41.853 に答える
8

Krishnabhadraによってここで解決策として与えられたコードに注意してください:

[[yourSuperView subviews]makeObjectsPerformSelector:@selector(setUserInteractionEnabled:) withObject:[NSNumber numberWithBool:FALSE]];

[yourSuperView subviews]はスーパービューの直接サブビューのみを提供するため、これはすべての場合に機能するとは限りません。それを機能させるには、すべてのサブビューを再帰的に繰り返す必要があります。

-(void) disableRecursivelyAllSubviews:(UIView *) theView
{
    theView.userInteractionEnabled = NO;
    for(UIView* subview in [theView subviews])
    {
        [self disableRecursivelyAllSubviews:subview];
    }
}

-(void) disableAllSubviewsOf:(UIView *) theView
{
    for(UIView* subview in [theView subviews])
    {
        [self disableRecursivelyAllSubviews:subview];
    }
} 

これで、への呼び出しはdisableAllSubviewsOfあなたがやりたいことをします。

ビューのスタックが深い場合は、lxtによるソリューションの方がおそらく優れています。

于 2012-07-18T17:25:42.977 に答える
5

これを行うには、と同じフレームのカスタム透明ボタンsuperViewを配置します。そして、そのボタンの上に、ユーザーのタッチを受け入れるビューを配置します。 ボタンはすべてのタッチを飲み込み、その背後にあるビューはタッチイベントを受信しませんが、ボタンの上部のビューは通常どおりタッチを受信します。

このようなもの:

- (void)disableTouchesOnView:(UIView *)view {
    UIButton *ghostButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, view.frame.size.width, view.frame.size.height)];
    [ghostButton setBackgroundColor:[UIColor clearColor]];
    ghostButton.tag = 42; // Any random number. Use #define to avoid putting numbers in code.

    [view addSubview:ghostButton];
}

そして、を有効にする方法parentView

- (void)enableTouchesOnView:(UIView *)view {
    [[view viewWithTag:42] removeFromSuperview];
}

したがって、parentViev背後yourViewにあるすべてのビューを無効にするには、次のようにします。

YourView *yourView = [[YourView alloc] initWithCustomInitializer];
// It is important to disable touches on the parent view before adding the top most view.
[self disableTouchesOnView:parentView];
[parentView addSubview:yourView];
于 2015-12-08T19:33:14.350 に答える
5

ただ parentView.UserInteractionEnabled = NO仕事をします。親ビューは、ビューのすべてのサブビューでのユーザー操作を無効にします。ただし、有効にすると、すべてのサブビューが有効になるわけではありません(デフォルトではUIImageViewは対話可能ではありません)。したがって、簡単な方法は、親ビューを見つけて上記のコードを使用することです。セレクターを実行するためにすべてのサブビューを繰り返す必要はありません。

于 2016-03-17T17:36:07.397 に答える
4

TapGestureRecognizerを「背景ビュー」(通常のインターフェースを「グレー表示」する半透明のビュー)に追加し、アクションを追加せずに「ビュー内のタッチをキャンセル」に設定します。

let captureTaps = UITapGestureRecognizer()
captureTaps.cancelsTouchesInView = true
dimmedOverlay?.addGestureRecognizer(captureTaps)
于 2015-09-18T09:13:34.667 に答える
2

私はこの問題に私の2セントを与えます。userInteractionEnabled=falseを繰り返し実行します。これは一方向です。別の方法は、次のようなUIViewを追加することです。

EZEventEater.h

#import <UIKit/UIKit.h>
@interface EZEventEater : UIView
@end

EZEventEater.m

#import "EZEventEater.h"
@implementation EZEventEater

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        self.backgroundColor = [UIColor clearColor];
        self.userInteractionEnabled = false;
    }
    return self;
}


- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
   //EZDEBUG(@"eater touched");
}

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{

}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{

}

コードでEZEventEaterビューを追加して、タッチイベントをブロックする可能性のあるすべてのビューをカバーします。これらのビューへのタッチイベントをブロックする場合は、いつでも電話してください

eater.userInteractionEnabled = YES;

これがお役に立てば幸いです。

于 2014-08-31T13:58:49.463 に答える
0

setUserInteractionEnabled = NO無効にするビューで

于 2011-03-23T12:01:44.420 に答える
0

私のアプリの場合、アプリの他のタブへのナビゲーションを無効にするだけで十分だと思います(処理を行っている間、限られた時間だけ):

self.tabBarController.view.userInteractionEnabled = NO;

また、現在のViewControllerを無効にしました--

self.view.userInteractionEnabled = NO;

(ちなみに、ここで提案された再帰的ソリューションは、私のアプリで奇妙な効果をもたらしました。無効化は正常に機能しているようですが、再有効化には奇妙な効果があります。一部のUIは再度有効化されませんでした)。

于 2013-02-25T04:25:37.513 に答える
0

Swift 5では、ビューを真上(強調表示されたもの)に配置し、次のように設定することで、この動作を実現しました。

myView.isUserInteractionEnabled = true

これにより、タッチが通過しないため、タップが無視されます。

ここに画像の説明を入力してください

于 2020-09-11T05:58:20.087 に答える
0

シンプルなソリューション。何もしないダミージェスチャを追加します。次のような拡張機能に追加して、再利用可能にします。

extension UIView {
    func addNullGesture() {
        let gesture = UITapGestureRecognizer(target: self,
                                             action: #selector(nullGesture))
        addGestureRecognizer(gesture)
    }
    
    @objc private func nullGesture() {}
}
于 2021-08-16T15:42:57.507 に答える
-1

私は同じ問題を抱えていましたが、上記の解決策は役に立ちませんでした。super.touchesBegan(...)それから私は電話が問題であることに気づき ました。これを削除した後、イベントは最上位のビューによってのみ処理されました。

これが誰かの助けになることを願っています。

于 2017-03-02T11:18:44.180 に答える