Displaying Touches On-screen in iOS with Touchposé

Todd Reed

The iPad 2 and iPhone 4S support display mirroring out-of-the-box. When connected to an external display (via cable or wirelessly with AirPlay), iOS will mirror the device’s display on the external display. This is a great feature when you need to demonstrate your iOS app to an audience of more than a few people. However, with the audience looking at an external display, and not you, there’s a major problem: they have no idea how you’re interacting with the app.

Touchposé showing four finger touches.

I wrote Touchposé to solve this problem. Touchposé adds a transparent overlay to your app’s UI; all touch events cause semi-transparent circles to be rendered on the overlay.

Touchposé should work for most apps (but read the caveat below). It’s implemented by a single public class, QTouchposeApplication, and several private classes. QTouchposeApplication overrides ‑sendEvent: and is responsible for rendering touches on the overlay view. There are some gnarly implementation bits to ensure that the overlay view remains the top-most view in the view hierarchy. This is achieved by intercepting calls to ‑didAddSubview: and ‑becomeKeyWindow using method swizzling. Method swizzling is supported by the Objective‑C runtime, but it’s usually considered a dangerous practice, especially when done on classes you don’t own. Furthermore, it only works if you’re the only one swizzling—if some other class is also swizzling methods on the same class, things may go amok. My recommendation is to only use this code in private builds when you want to demo your app to an audience on a projector.

To use Touchposé with an app, indicate that QTouchposeApplication should be used instead of UIApplication. This is done by specifying the application class in UIApplicationMain:

int main(int argc, char *argv[])
        return UIApplicationMain(argc, argv,
                                 NSStringFromClass([QTouchposeApplication class]),
                                 NSStringFromClass([QAppDelegate class]));

That’s it; no other steps are needed. By default, touch events are only displayed when actually connected to an external device. If you want to always show touch events, set the alwaysShowTouches property of QTouchposeApplication to YES.

Touchposé is available on GitHub.

✻ The name “Touchposé” is shamelessy pilfered and refashioned from Boinx Software’s Mouseposé, which serves a similar purpose as Touchposé, but for the desktop. ↩︎

† There are now a myriad of spelling variations in use, including “TouchPosé”, “TouchPose”, “Touchpose”, and “TouchPosè”. The intended pronunciation was tuhch-poh-zay, but all the YouTube reviewers of the Cydia tweak are pronouncing it tuhch-pohz. Oh well. ↩︎