I'm implementing an iOS video player using AVPlayerViewController
with custom playback controls (i.e., the showsPlaybackControls
property is defined as NO
). This seems to work properly in most cases, the only issue I'm seeing is that I would like to use a custom activity indicator with the player as well, but it seems that AVPlayerViewController
shows a default activity indicator while buffering the video at some points.
Is there a way to remove this default activity indicator view from AVPlayerViewController
?
The image shows what I'm describing, the controls at the bottom are custom and overlaid on top of the player, but the activity indicator is not.
I made an extension of AVPlayerViewController
that exposes the internal activity indicator. Here you go, with all the Swift 3 sexiness:
import AVKit
extension AVPlayerViewController {
/// Activity indicator contained nested inside the controller's view.
var activityIndicator: UIActivityIndicatorView? {
// Indicator is extracted by traversing the subviews of the controller's `view` property.
// `AVPlayerViewController`'s view contains a private `AVLoadingIndicatorView` that
// holds an instance of `UIActivityIndicatorView` as a subview.
let nestedSubviews: [UIView] = view.subviews
.flatMap { [$0] + $0.subviews }
.flatMap { [$0] + $0.subviews }
.flatMap { [$0] + $0.subviews }
return nestedSubviews.filter { $0 is UIActivityIndicatorView }.first as? UIActivityIndicatorView
}
/// Indicating whether the built-in activity indicator is hidden or not.
var isActivityIndicatorHidden: Bool {
set {
activityIndicator?.alpha = newValue ? 0 : 1
}
get {
return activityIndicator?.alpha == 0
}
}
}
With this, you can either easily style the UIActivityIndicatorView
or just hide it all together, e.g.:
playerViewController.isActivityIndicatorHidden = true
I also searched for this solution and the way I managed to make it is hide video player view controllers view once I started playing video and when video is ready to play I show it again.
private func playVideo() {
videoPlayer?.play()
self.addLoader()
videoPlayerController.view.hidden = true
videoPlayer?.addObserver(self, forKeyPath: "status", options: NSKeyValueObservingOptions.New, context: nil)
}
public override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
if (object?.isEqual(videoPlayer) == true && keyPath == "status") {
self.removeLoader()
videoPlayerController.view.hidden = false
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With