{"id":5247,"date":"2016-09-12T13:05:12","date_gmt":"2016-09-12T12:05:12","guid":{"rendered":"http:\/\/www.thetawelle.de\/?p=5247"},"modified":"2016-09-12T13:49:02","modified_gmt":"2016-09-12T12:49:02","slug":"developing-for-tvos-using-the-remote-layout-helper","status":"publish","type":"post","link":"https:\/\/www.thetawelle.de\/?p=5247","title":{"rendered":"Developing for tvOS using the Remote Layout Helper"},"content":{"rendered":"<p>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.<\/p>\n<p>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 <strong>Remote Layout Helper<\/strong>).<\/p>\n<p><center><a href=\"\/wp-upload\/tvOS_screen_size.png\"><img loading=\"lazy\" decoding=\"async\" src=\"\/wp-upload\/tvOS_screen_size-1024x576.png\" alt=\"tvOS Layout Template\" width=\"840\" height=\"473\" class=\"aligncenter size-large wp-image-5248\" srcset=\"https:\/\/www.thetawelle.de\/wp-upload\/tvOS_screen_size-1024x576.png 1024w, https:\/\/www.thetawelle.de\/wp-upload\/tvOS_screen_size-300x169.png 300w, https:\/\/www.thetawelle.de\/wp-upload\/tvOS_screen_size-768x432.png 768w, https:\/\/www.thetawelle.de\/wp-upload\/tvOS_screen_size-1200x675.png 1200w, https:\/\/www.thetawelle.de\/wp-upload\/tvOS_screen_size.png 1920w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/a><br \/><small><a href=\"\/wp-upload\/tvOS_screen_size.png\">Download the Overlay Image<\/a> (use Save as&#8230;)<\/small><\/center><\/p>\n<p>On my main controller I added &#038; called following method which I call in <code>- (void) viewDidAppear:(BOOL)animated<\/code>:<\/p>\n<pre class=\"brush: cpp; gutter: true; title: Source\/Snippet; toolbar: true; notranslate\" title=\"Source\/Snippet\">\r\n- (void) activateCalibrationOverlay {\r\n    if( DEBUG_CALIBRATION_OVERLAY ) {\r\n        if( !overlayImageView ) {\r\n            self.overlayImageView = &#x5B;&#x5B;UIImageView alloc] initWithImage:&#x5B;UIImage imageNamed:@&quot;tvOS_screen_size.png&quot;]];\r\n            overlayImageView.alpha = 0.0;\r\n            overlayImageView.userInteractionEnabled = NO;\r\n            &#x5B;&#x5B;self appDelegate].window addSubview:overlayImageView];\r\n            &#x5B;&#x5B;self appDelegate].window bringSubviewToFront:overlayImageView];\r\n            if( !overlayPlayPauseGesture ) {\r\n                self.overlayPlayPauseGesture = &#x5B;&#x5B;UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleRemoteTapPlayPause:)];\r\n                overlayPlayPauseGesture.allowedPressTypes = @&#x5B;&#x5B;NSNumber numberWithInteger:UIPressTypePlayPause]];\r\n                &#x5B;self.view addGestureRecognizer:overlayPlayPauseGesture];\r\n            }\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>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:<\/p>\n<pre class=\"brush: cpp; gutter: true; title: Source\/Snippet; toolbar: true; notranslate\" title=\"Source\/Snippet\">\r\n-(void)handleRemoteTapPlayPause:(UIGestureRecognizer*)tapRecognizer {\r\n    if( overlayImageView.alpha == 0.0f ) {\r\n        &#x5B;UIView animateWithDuration:0.3 animations:^{\r\n            overlayImageView.alpha = 0.3;\r\n        }];\r\n        return;\r\n    }\r\n    if( overlayImageView.alpha == 0.3f ) {\r\n        &#x5B;UIView animateWithDuration:0.3 animations:^{\r\n            overlayImageView.alpha = 0.5;\r\n        }];\r\n        return;\r\n    }\r\n    if( overlayImageView.alpha == 0.5f ) {\r\n        &#x5B;UIView animateWithDuration:0.3 animations:^{\r\n            overlayImageView.alpha = 0.8;\r\n        }];\r\n        return;\r\n    }\r\n    if( overlayImageView.alpha == 0.8f ) {\r\n        &#x5B;UIView animateWithDuration:0.3 animations:^{\r\n            overlayImageView.alpha = 1.0;\r\n        }];\r\n        return;\r\n    }\r\n    if( overlayImageView.alpha == 1.0f ) {\r\n        &#x5B;UIView animateWithDuration:0.3 animations:^{\r\n            overlayImageView.alpha = 0.0;\r\n        }];\r\n        return;\r\n    }\r\n}\r\n<\/pre>\n<p>This helped me a lot doing the right things during development. I hope it helps you too. Feel free to share!<\/p>\n<h2>How to use it<\/h2>\n<p>You simply press PLAY\/PAUSE again and again and the overlay will fade in at different alpha-blending-levels between <code>0.0<\/code> and <code>1.0<\/code>. This allows to easily check boundaries of UI elements displayed against the screenlimits.<\/p>\n<p>See following screen example:<br \/>\n<figure id=\"attachment_5258\" aria-describedby=\"caption-attachment-5258\" style=\"width: 840px\" class=\"wp-caption aligncenter\"><a href=\"\/wp-upload\/tvOS_screen_overlay_action.png\"><img loading=\"lazy\" decoding=\"async\" src=\"\/wp-upload\/tvOS_screen_overlay_action-1024x576.png\" alt=\"The overlay in action on an app displayed.\" width=\"840\" height=\"473\" class=\"size-large wp-image-5258\" srcset=\"https:\/\/www.thetawelle.de\/wp-upload\/tvOS_screen_overlay_action-1024x576.png 1024w, https:\/\/www.thetawelle.de\/wp-upload\/tvOS_screen_overlay_action-300x169.png 300w, https:\/\/www.thetawelle.de\/wp-upload\/tvOS_screen_overlay_action-768x432.png 768w, https:\/\/www.thetawelle.de\/wp-upload\/tvOS_screen_overlay_action-1200x675.png 1200w, https:\/\/www.thetawelle.de\/wp-upload\/tvOS_screen_overlay_action.png 1920w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/a><figcaption id=\"caption-attachment-5258\" class=\"wp-caption-text\">The overlay in action on an app displayed.<\/figcaption><\/figure><\/p>\n<p>Recognize, that you need a retained variable for the UIImageView called <code>overlayImageView<\/code> and another for the tap gesture recognizer called <code>overlayPlayPauseGesture<\/code> to be overlaid. And recognize that I use a boolean Precompiler-Flag named <code>DEBUG_CALIBRATION_OVERLAY<\/code> to switch this feature OFF in deployment.<\/p>\n<p><small><strong>Why do I blog this?<\/strong> 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!)<\/small><\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 &hellip; <a href=\"https:\/\/www.thetawelle.de\/?p=5247\" class=\"more-link\"><span class=\"screen-reader-text\">\u201eDeveloping for tvOS using the Remote Layout Helper\u201c <\/span>weiterlesen<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17,88,67,59],"tags":[],"class_list":["post-5247","post","type-post","status-publish","format-standard","hentry","category-best-practice","category-coding","category-english","category-iphone"],"_links":{"self":[{"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=\/wp\/v2\/posts\/5247","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=5247"}],"version-history":[{"count":0,"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=\/wp\/v2\/posts\/5247\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5247"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5247"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5247"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}