0

我正在为 tvOS 编写一个应用程序,它将视频从 URL 启动到 AVPlayerView 中,该 AVPlayerView 没有嵌套在另一个视图中。问题是,用户在加载时不知道发生了什么,所以我想在屏幕中央添加一个活动指示器。

但是,在加载视频时获取屏幕中心并不简单,因为在加载视频时视图的边界设置为 (0, 0, 0, 0),因此设置子视图的 center = view.center 不起作用(它只会在屏幕的左上角添加我的子视图)。

当框架设置为 (0, 0, 0, 0) 时,如何将子视图添加到屏幕中心?

4

1 回答 1

0

幸运的是,我能够自己找到答案。UIScreen 在 tvOS 上与在 iOS 设备上一样好用。我的完整解决方案如下,希望它可以帮助节省一些时间。我也包括触发结局的观察者。

我用来处理活动的类

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

这是您使用 UIScreen 获取边界的部分

    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

我添加了一个标签以增加清晰度

    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()
}

然后在要添加一些加载活动的 AVPlayerViewController 中...

首先创建活动指示器对象:

let indicator = VideoLoadingActivityIndicator()

创建您的资产和 playerItem(我设置了一些播放器项目键)

let asset = AVAsset(url: runFile)
let assetKeys = [
        "playable",
        "hasProtectedContent"
    ]
let playerItem = AVPlayerItem(asset: asset, automaticallyLoadedAssetKeys: assetKeys)

启动活动指示器动画

indicator.beginLoadingActivity(viewController: self, color: .white)

向播放器添加通知并开始播放

playerItem.addObserver(self, forKeyPath: "status", options: NSKeyValueObservingOptions.new, context: nil)
player = AVPlayer(playerItem: playerItem)
    player?.play()

最后,处理观察者:

    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)
    }
}

希望这可以帮助遇到我遇到的一些相同问题的其他人。

于 2017-11-15T20:55:53.127 回答