user8105330
user8105330

Reputation:

Adding overlay buttons to tvOS AVPlayerViewController

I'm trying to build an overlay that appears over an AVPlayer when I press pause. The problem I'm having is that while I can overlay buttons just fine I can't get the focus engine in tvOS to focus on them... I'm pretty sure this is happening as the player frame robs focus (it's fullscreen @ 1080p) and I can't focus on objects that are inside of its frame.

Pseudo code for what I'm doing:

class MyViewController: UIViewController {
    var playerController = AVPlayerViewController()
    @IBOutlet weak var button: UIButton! // button centred on screen that requires focus

    override func viewDidLoad() {
        super.viewDidLoad()
        self.playerController.player = AVPlayer(url: myURL)
        self.playerController.view.frame = self.view.bounds
        self.view.addSubview(self.playerController.view)
        self.view.bringSubview(toFront: self.button)
    }

    // ... functions that enable listeners and show/hide button when self.playerController.player rate changes
}

What I want is to be able to press pause, then swipe up to get focus on the button(s) instead of the seek bar and then swipe back down to the seek bar if needed. Much like the Apple Music application that comes with the tvOS.

Thanks.

Upvotes: 1

Views: 2157

Answers (2)

Igor Zhukov
Igor Zhukov

Reputation: 71

You can set desired custom vc with action items to var customOverlayViewController: UIViewController? { get set } of your AVPlayerViewController instance. (available from tvOS 13)

Official documentation states:

When the transport bar is hidden, the player view controller presents the overlay view controller’s view when a user swipes up on the Siri Remote during playback. Use this property to set a custom view controller instead of installing your own swipe gesture recognizer.

https://developer.apple.com/documentation/avkit/avplayerviewcontroller/3229856-customoverlayviewcontroller

You can also check this video starting from 26:07 to see it in action. https://developer.apple.com/videos/play/wwdc2019/503

P.S. Don't use var contentOverlayView: UIView? { get } to display interactable content, as official documentation states:

Use the content overlay view to add noninteractive custom views, such as a logo or watermark, between the video content and the controls.

https://developer.apple.com/documentation/avkit/avplayerviewcontroller/1615835-contentoverlayview

Upvotes: 1

user8105330
user8105330

Reputation:

My solution is to override preferredFocusEnvironment and add some listeners to the parent VC to change a condition when certain actions are taken...not perfect but good enough.

override var preferredFocusEnvironment {
    if self.someCondition {
        return [self.button]
    }
    else {
        return [self.playerController.view]
    }
}

Upvotes: 0

Related Questions