Luckily, I was able to find the answer on my own. UIScreen works just as well with tvOS as it would on an iOS device. My complete solution is below, hope it helps save someone some time. I am including my observers that trigger the end as well.
The class that I used to handle the activity
class VideoLoadingActivityIndicator {
var loadingActivityIndicator:UIActivityIndicatorView!
var loadingLabel: UILabel!
func beginLoadingActivity(viewController:UIViewController)
{
loadingActivityIndicator = UIActivityIndicatorView(frame:CGRect(x: 500, y: 500, width: 500, height: 500)) as UIActivityIndicatorView
loadingActivityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.whiteLarge
loadingActivityIndicator.sizeToFit()
loadingActivityIndicator.color = UIColor.white
This is the part where you use UIScreen to get the bounds
let screenBounds = UIScreen.main.bounds
let centerX = screenBounds.size.width / 2
let centerY = screenBounds.size.height / 2
let loadingLabelCenterY = centerY + 48
let activityIndicatorCenter = CGPoint(x: centerX, y: centerY)
loadingActivityIndicator.center = activityIndicatorCenter
I added a label to add some clarity
loadingLabel = UILabel(frame: CGRect(x: centerX, y: loadingLabelCenterY, width: 600, height: 100))
loadingLabel.font = UIFont(name: "Helvetica", size: 30)
loadingLabel.text = "Loading Video"
loadingLabel.numberOfLines = 1
loadingLabel.sizeToFit()
loadingLabel.textAlignment = .center
// reset frame so it is centered in screen
let labelWidth = loadingLabel.frame.width
let labelHeight = loadingLabel.frame.height
let loadingLabelCenterX = centerX - (labelWidth / 2)
loadingLabel.frame = CGRect(x: loadingLabelCenterX, y: loadingLabelCenterY, width: labelWidth, height: labelHeight)
loadingLabel.textColor = UIColor.white
// Add indicator and label to subview
viewController.view.addSubview(loadingActivityIndicator)
viewController.view.addSubview(loadingLabel)
self.loadingActivityIndicator.startAnimating()
}
func endLoadingActivity(viewController:UIViewController)-> Void
{
loadingActivityIndicator.removeFromSuperview()
loadingLabel.removeFromSuperview()
}
And then in the AVPlayerViewController that you want to add some the loading activity to...
First create the activity indicator object:
let indicator = VideoLoadingActivityIndicator()
Create your asset, and playerItem (I set some player item keys)
let asset = AVAsset(url: runFile)
let assetKeys = [
"playable",
"hasProtectedContent"
]
let playerItem = AVPlayerItem(asset: asset, automaticallyLoadedAssetKeys: assetKeys)
start the activity indicator animations
indicator.beginLoadingActivity(viewController: self, color: .white)
Add notification to player and start playback
playerItem.addObserver(self, forKeyPath: "status", options: NSKeyValueObservingOptions.new, context: nil)
player = AVPlayer(playerItem: playerItem)
player?.play()
Finally, handle the observer:
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "status" && player?.status == AVPlayerStatus.readyToPlay {
indicator.endLoadingActivity(viewController: self)
}
}
Hope this helps someone else who runs into some of the same issues I did.