Developing for tvOS using the Remote Layout Helper

I am developing an app for tvOS. One thing you quickly run into when testing on real world devices is the limits of screensize on several TV models. For this apple added a calibration tool in the settings.

I found I needed this info to actually make my UI layout work for customers. So I took a screenshot and created this screenimage as (PNG) to overlay it at any time in the dev-process for orientation of myself as a Remote Layout Helper).

tvOS Layout Template
Download the Overlay Image (use Save as…)

On my main controller I added & called following method which I call in - (void) viewDidAppear:(BOOL)animated:

- (void) activateCalibrationOverlay {
    if( DEBUG_CALIBRATION_OVERLAY ) {
        if( !overlayImageView ) {
            self.overlayImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"tvOS_screen_size.png"]];
            overlayImageView.alpha = 0.0;
            overlayImageView.userInteractionEnabled = NO;
            [[self appDelegate].window addSubview:overlayImageView];
            [[self appDelegate].window bringSubviewToFront:overlayImageView];
            if( !overlayPlayPauseGesture ) {
                self.overlayPlayPauseGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleRemoteTapPlayPause:)];
                overlayPlayPauseGesture.allowedPressTypes = @[[NSNumber numberWithInteger:UIPressTypePlayPause]];
                [self.view addGestureRecognizer:overlayPlayPauseGesture];
            }
        }
    }
}

This adds an overlay of the Remote Layout Helper screen image on TOP of everything else and a gesture recognizer monitoring the PLAY/PAUSE-button of the TV remote. It calls following method:

-(void)handleRemoteTapPlayPause:(UIGestureRecognizer*)tapRecognizer {
    if( overlayImageView.alpha == 0.0f ) {
        [UIView animateWithDuration:0.3 animations:^{
            overlayImageView.alpha = 0.3;
        }];
        return;
    }
    if( overlayImageView.alpha == 0.3f ) {
        [UIView animateWithDuration:0.3 animations:^{
            overlayImageView.alpha = 0.5;
        }];
        return;
    }
    if( overlayImageView.alpha == 0.5f ) {
        [UIView animateWithDuration:0.3 animations:^{
            overlayImageView.alpha = 0.8;
        }];
        return;
    }
    if( overlayImageView.alpha == 0.8f ) {
        [UIView animateWithDuration:0.3 animations:^{
            overlayImageView.alpha = 1.0;
        }];
        return;
    }
    if( overlayImageView.alpha == 1.0f ) {
        [UIView animateWithDuration:0.3 animations:^{
            overlayImageView.alpha = 0.0;
        }];
        return;
    }
}

This helped me a lot doing the right things during development. I hope it helps you too. Feel free to share!

How to use it

You simply press PLAY/PAUSE again and again and the overlay will fade in at different alpha-blending-levels between 0.0 and 1.0. This allows to easily check boundaries of UI elements displayed against the screenlimits.

See following screen example:

The overlay in action on an app displayed.
The overlay in action on an app displayed.

Recognize, that you need a retained variable for the UIImageView called overlayImageView and another for the tap gesture recognizer called overlayPlayPauseGesture to be overlaid. And recognize that I use a boolean Precompiler-Flag named DEBUG_CALIBRATION_OVERLAY to switch this feature OFF in deployment.

Why do I blog this? I found it cumbersome to check against real world TV screens if my app works. So I just made sure that most of my UI is usable from within the MINIMUM SCREENSIZE frame the overlay gfx displays to me. Checking this anytime using the remote is a huge plus also on the real device. (Do not forget to disable the code on deployment!)

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.