web-dev-qa-db-ja.com

iOSでは、スーパービューのuserInteractionEnabledがNOの場合、すべてのサブビューも無効になりますか?

ビューがタッチまたはタップされると、そのハンドラーが最初に呼び出され、次にそのスーパービューのハンドラーが呼び出されます(上方向に伝搬)。

しかし、スーパービューのuserInteractionEnabledがNOに設定されている場合、すべてのサブビューと子孫もユーザーの操作に対して無効になるのは本当ですか?メインビューだけを無効にしたいが、サブビューは無効にしたくない場合はどうなりますか?

28
nonopolarity

あなたはそれをすることはできません、

代わりに、次のようにビューの配置を変更します。

Main View-> subViews

Container View -> Main View that you want to set as inactive
               -> other views that you want to still active

したがって、現在のメインビューと現在のサブビューは兄弟になり、新しいコンテナビューの子になります

16

これが役立つ場合は、Matt Neuburg著 『Programming iOS 5』(p。 467:

userInteractionEnabled

NOに設定されている場合、このビュー(およびそのサブビュー)はタッチの受信から除外されます。このビューまたはそのサブビューの1つをタッチすると、その背後のビューに「フォールスルー」します。

さらに、AppleのiOS向けイベント処理ガイドには次のように書かれています。

ウィンドウオブジェクトは、ヒットテストとレスポンダーチェーンを使用して、タッチイベントを受け取るビューを見つけます。ヒットテストでは、ウィンドウがビュー階層の最上位のビューでhitTest:withEvent:を呼び出します。このメソッドは、YESを返すビュー階層の各ビューでpointInside:withEvent:を再帰的に呼び出し、タッチが行われた境界内のサブビューが見つかるまで階層を下っていきます。そのビューがヒットテストビューになります。

matt Neuburgによる 『Programming iOS 5』 p.485では、ビューにuserInteractionEnabledNOとしてマークした場合、またはhiddenYESとしてマークした場合、または不透明度が0に近い場合、ビューとそのサブビューはHitTestによってトラバースされません(したがって、タッチは考慮されません)。

25

hitTest(_:withEvent:)をオーバーライドしてビュー自体を無視することができますが、そのサブビューにタッチを配信できます。

class ContainerStackView : UIStackView {
    override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
        let result = super.hitTest(point, withEvent: event)
        if result == self { return nil }
        return result
    }
}
19

最初の方法

- (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
  if ([touch.view.superview isKindOfClass:[SuperViewParent class]]) return FALSE;
  return TRUE;
}

2番目の方法

UITapGestureRecognizer *r = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(agentPickerTapped:)];
    r.cancelsTouchesInView = NO;
    [agentPicker addGestureRecognizer:r];
1
Xar E Ahmer