ビューがタッチまたはタップされると、そのハンドラーが最初に呼び出され、次にそのスーパービューのハンドラーが呼び出されます(上方向に伝搬)。
しかし、スーパービューのuserInteractionEnabled
がNOに設定されている場合、すべてのサブビューと子孫もユーザーの操作に対して無効になるのは本当ですか?メインビューだけを無効にしたいが、サブビューは無効にしたくない場合はどうなりますか?
あなたはそれをすることはできません、
代わりに、次のようにビューの配置を変更します。
Main View-> subViews
に
Container View -> Main View that you want to set as inactive
-> other views that you want to still active
したがって、現在のメインビューと現在のサブビューは兄弟になり、新しいコンテナビューの子になります
これが役立つ場合は、Matt Neuburg著 『Programming iOS 5』(p。 467:
userInteractionEnabled
NOに設定されている場合、このビュー(およびそのサブビュー)はタッチの受信から除外されます。このビューまたはそのサブビューの1つをタッチすると、その背後のビューに「フォールスルー」します。
さらに、AppleのiOS向けイベント処理ガイドには次のように書かれています。
ウィンドウオブジェクトは、ヒットテストとレスポンダーチェーンを使用して、タッチイベントを受け取るビューを見つけます。ヒットテストでは、ウィンドウがビュー階層の最上位のビューでhitTest:withEvent:を呼び出します。このメソッドは、YESを返すビュー階層の各ビューでpointInside:withEvent:を再帰的に呼び出し、タッチが行われた境界内のサブビューが見つかるまで階層を下っていきます。そのビューがヒットテストビューになります。
matt Neuburgによる 『Programming iOS 5』 p.485では、ビューにuserInteractionEnabled
をNO
としてマークした場合、またはhidden
をYES
としてマークした場合、または不透明度が0に近い場合、ビューとそのサブビューはHitTest
によってトラバースされません(したがって、タッチは考慮されません)。
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
}
}
最初の方法
- (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];