0

私は解決策を探していましたが、幸運にも解決策を見つけることができませんでした。以前に尋ねられたことがあれば、誰かが指摘したり、アイデアを手伝ってくれたりするかもしれません。

UIViewController2つのカスタム ビューをホストしています。最初のカスタム ビューは全画面表示です。2 番目のカスタム ビューは、実際には画面の下部からビューにスライドするメニューであり、カスタム アニメーションを含むツールバーと同様に、スライドして表示されます。

現在の構成:メニューは遅延の後 (ビューが表示された後) ビューにスライドし、NSTimer がカウントを開始します。NSTimer が別のメソッドを起動し、そのメソッドがメニューを元に戻すまで、数秒間ビューに残ります。

すべて正常に動作します。

私が欲しいもの:ユーザーがメニューの操作、スイッチ、スライダーの切り替えなどを開始した場合、ユーザーが操作を完了するまで、NSTimer の起動を遅らせて、メニューをビューにとどめておきます。次に、メニューを撤回します。

これを実現するために、メニューをビューにスライドさせるメソッドで NSTimer を使用して、X ミリ秒後にメニューを撤回する別のメソッドを起動しました。

メニューを撤回するメソッドでは、タイマーを無効にしています。

メソッドをtocuhesBeganオーバーライドして、相互作用の領域がメニューの境界内に収まるかどうかを確認しました。そうであれば、NSTimer がさらに X ミリ秒リセットされます。

問題:ユーザーがメニューの背景に触れた場合は問題ありませんが、ユーザーがメニュー内のスイッチ、ボタン、およびスライドを操作した場合、menu.viewタッチが登録されません。であるため、タッチ イベントは階層に渡されません。しかし一方で、それは私の問題です!!

touchesBeganのすべての要素のすべてのメソッドをオーバーライドすることはできませんmenu.view。menu.view の領域で発生しているタッチを他にどのように登録できますか?

ウィンドウ内でタッチしようとlocationInView:nilしましたが、ボタンやスライダーなどの操作も登録されません。

ありがとう。

4

1 に答える 1

1

ビュー階層内で発生するすべてのタッチイベントをキャプチャする1つのソリューションは、カスタムUIWindow実装を提供し、sendEventメソッドをオーバーライドすることです。すべてのイベントは、UIApplication最初に受信され、次にディスパッチさUIWindowれてから、UIView含まれているタッチポイントにディスパッチされます。UIWindowレベルでイベントをキャッチすることにより、各コントロールをオーバーライドすることなく、すべてのイベントをインターセプトできるようになります。

カスタムUIWindowクラスを作成し、次のsendEventように実装します。

- (void)sendEvent:(UIEvent *)event 
{
    // Notify app to reset menu timer
    // ...

    [super sendEvent:event];
}

バニラの代わりにカスタムUIWindowを使用するかどうかは、UIの実装方法によって異なります。ストーリーボードを使用している場合は、次のwindowようにアプリデリゲートにgetterメソッドを実装する必要があります。

- (UIWindow*)window
{
    if (!_window) {
        _window = [[CustomWindow alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
    }

    return _window;
}

application:didFinishLaunchingWithOptions:それ以外の場合は、アプリデリゲートのメソッドで標準のUIWindowの代わりにカスタムUIWindowのインスタンスを作成します。

タッチイベントの通知を受信するには、いくつかのオプションがあります。NSNotificationCenterを使用してカスタム通知を送信およびサブスクライブするか、カスタムUIWindowにデリゲートプロパティを実装し、タッチイベントの通知を受信するデリゲートとしてUIViewControllerを設定できます。

于 2012-01-31T18:29:37.377 に答える