I have been looking for a solution, and haven’t been lucky to find one. If it has been asked before, mayboe some one can point it out, or help me with an idea.
I have UIViewController that hosts tow custom views. The first custom view is full screen. The second custom view, is actually is a menu that slides into the view from the bottom of the screen, similar to a toolbar with custom animation, and then it should slides out.
Current confirguation: the menu slides into the view after a delay (after view appears), and a NSTimer starts counting. It remains in the view for few seconds, until the NSTimer fires another method, and that method retracts the menu back.
Everything works fine.
What I want: If user starts interacting with the menu, toggling switches, slider, etc, I want the menu to stay in the view, delaying the firing of NSTimer, until user is done interacting. Then retract the menu.
To accomplish this, I used a NSTimer in the method that slides the menu into the view, to fire the other method that retracts the menu after X msec.
In the method that retracts the menu, I invalidate the timer.
I overrode the tocuhesBegan method, to see if the area of interaction falls within the boundries of the menu, if so, the NSTimer is resetted for another X msec.
Problem: If user touches the background of the menu, it is fine, but if user interacts with switches, buttons and slides within the menu, the menu.view does not register touches, which makes sense, because they are the front line and exhaust the touch event, so the touch event does not get passed down the hierarchy. But on the other hand, that is my problem!!
I can’t override every touchesBegan method in every element in the menu.view. How else can I register for those touches that are happening in the area of the menu.view?
I tried locationInView:nil to get touches within the window, but that dosen’t register interactions with buttons and sliders, etc, either.
Thanks.
One solution to capture all touch events wherever they occur in your view hierarchy is to provide a custom UIWindow implementation and override the
sendEventmethod. All events are received by theUIApplicationfirst then dispatched toUIWindowbefore being dispatched to theUIViewcontaining the touch point. By catching the events at the UIWindow level you ensure that you can intercept every event without having to override each control.Create a custom UIWindow class and implement
sendEventlike this:To use your custom UIWindow instead of the vanilla one depends on how your UI is implemented. If you are using Storyboards then you need to implement a
windowgetter method on your app delegate like this:Otherwise create an instance of your custom UIWindow instead of the standard one in your app delegate’s
application:didFinishLaunchingWithOptions:method.You have several options for receiving the notification of touch events. You could use NSNotificationCenter to send and subscribe to a custom notification or you could implement a delegate property on your custom UIWindow and set your UIViewController as the delegate to receive notifications of touch events.