10 Tips for Mastering the Focus Engine on tvOS
iOSApplications that run on the Apple TV present an entirely new method of interaction compared to mobile and desktop applications. Instead of directly interacting...
The motion effect in tvOS is one of the key user interface foundations that make it a great user experience. Subtle movements on the Siri Remote cause similar movements on the focused item in the user interface. This gives users a clear sense of which element has focus, and gives life to the interface. Another foundation for the tvOS interface is the rich use of images throughout applications. Combining these two foundations is a property on UIImageView called adjustsImageWhenAncestorFocused
. This allows a UIImageView to respond to movements on the Siri Remote and adjust the image with subtle 3D movement.
There are cases when you want to go further with this effect, especially when your design calls for additional elements displayed on top of an image. In my last blog post on 10 Tips for Mastering the Focus Engine on tvOS, you learned how to create a rich UIButton using a separate XIB file and a UIView subclass. This allowed for overlaying elements on top of an image while still having a nice motion effect. One downside to this approach that you might have found is that rendering this view to an image can take some time. When attempting to use this approach inside a UICollectionView with many items, performance starts to become an issue.
overlayContentView
Now with tvOS 11, Apple has given us a powerful way to improve this technique. UIImageView now has a subview named overlayContentView
that receives the same motion effect that is applied to the UIImageView itself. This motion effect also applies to any subviews of overlayContentView
.
With this property, you can get very nice looking motion for badges, text and other types of views. The overlayContentView
is sized to match the underlying UIImageView, and is clipped to the bounds of the UIImageView by default. You can set the overlayContentView.clipsToBounds
to false to allow the overlayed views to be visible outside of the UIImageView.
Although you can add subviews to the overlayContentView
programatically, you still might want to design the overlaid content using Interface Builder. To accomplish this, we can use our same technique of creating a separate XIB file with a UIView subclass for all the overlay content, but instead of turning that into an image, we add that view as a subview of overlayContentView
. In addition to eliminating the need to render out our view as a UIImage, we also get the benefit of using AutoLayout in our UIView subclass and having it be sized correctly when put into the overlayContentView
.
Instead of the loadImageFromView(frame:)
method from our last post, we can create a much simpler version that just instantiates our view from the XIB and returns it:
static func loadView() -> ButtonView {
let name = String(describing: self)
guard let view = Bundle.main.loadNibNamed(name, owner: nil, options: nil) else {
preconditionFailure("Missing nib with name (name)")
}
guard let buttonView = view.first as? ButtonView else {
preconditionFailure("Cannot downcast message view as ButtonView")
}
return buttonView
}
To apply this view as an overlay to our UIImageView, add the view as a subview of overlayContentView
. Then setup AutoLayout constraints to make sure our UIView subview will match the size of the UIImageView:
let overlayView = ButtonView.loadView()
let overlayContentView = imageView.overlayContentView
overlayContentView.addSubview(overlayView)
overlayView.translatesAutoresizingMaskIntoConstraints = false
overlayView.leadingAnchor.constraint(equalTo: overlayContentView.leadingAnchor).isActive = true
overlayView.trailingAnchor.constraint(equalTo: overlayContentView.trailingAnchor).isActive = true
overlayView.topAnchor.constraint(equalTo: overlayContentView.topAnchor).isActive = true
overlayView.bottomAnchor.constraint(equalTo: overlayContentView.bottomAnchor).isActive = true
Although tvOS 11 didn’t bring many huge changes, there are many smaller improvements such as this that solve real challenges we have encountered while building tvOS applications for our clients. We can’t wait to see what is next for tvOS!
Learn more about why you should update your apps for iOS 11 before launch day, or download our ebook for a deeper look into how the changes affect your business.
Applications that run on the Apple TV present an entirely new method of interaction compared to mobile and desktop applications. Instead of directly interacting...
Swift allows for chaining methods together to perform powerful operations in a single line of code. If you aren’t careful, however, this can lead...