AVPlayer / AVPlayerLayer没有出现在使用自动布局的子视图中

时间:2015-11-11 15:23:56

标签: swift avfoundation ios9 avkit

我正在尝试在包含视频和一些文字的子视图中显示视频。我使用recommended UIView subclass from Apple创建了一个UIView来包含我的AVPlayer:

import Foundation
import AVFoundation

class JSAVPlayerView : UIView {
    var player:AVPlayer? {
        get {
            return (self.layer as! AVPlayerLayer).player
        }
        set(newPlayer) {
            (self.layer as! AVPlayerLayer).player = newPlayer
        }
    }

    override class func layerClass() -> AnyClass {
        return AVPlayerLayer.self
    }
}

我使用JSAVPlayerView作为UICollectionViewCell中的子视图,如下所示,但我只看到JSAVPlayerView的背景。

class JSOnBoardingTutorialPageView : UICollectionViewCell {
    // MARK: member variables
    private var tutorialVideoPlayer:AVPlayer!
    private var videoPlayerView:JSAVPlayerView = JSAVPlayerView()
    private var tutorialLabel:UILabel = UILabel()
    var tutorialText:String = "" {
        didSet {
            tutorialLabel.text = tutorialText
        }
    }

    // MARK: auto layout variables
    private var metrics:[String:CGFloat] = [
        "marginTop" : 30,
        "marginLeft" : 30,
        "marginRight" : 30,
        "marginBottom" : 30,
        "textHeight" : 100,
    ]
    private var autolayoutConstraints:[NSLayoutConstraint] = [NSLayoutConstraint]()







    // MARK: constructors
    override init(frame: CGRect) {
        super.init(frame: frame)

        self.backgroundColor = UIColor.jsBrandBlack()

        self.setupSubviews()
    }

    init() {
        super.init(frame: CGRect.zero)

        self.backgroundColor = UIColor.jsBrandBlack()

        self.setupSubviews()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }







    // MARK: subview setup
    func setupSubviews() {
        self.setupTutorialVideoView()
        self.setupTutorialLabel()

        self.setupConstraints()

        self.addConstraints(self.autolayoutConstraints)
    }

    func setupTutorialVideoView() {
        self.videoPlayerView.translatesAutoresizingMaskIntoConstraints = false

        self.videoPlayerView.backgroundColor = UIColor.blueColor()

        if let player = self.tutorialVideoPlayer {
            self.videoPlayerView.player = player
        }

        self.addSubview(self.videoPlayerView)
    }

    func setupTutorialLabel() {
        self.tutorialLabel.translatesAutoresizingMaskIntoConstraints = false
        self.tutorialLabel.textColor = UIColor.jsLightGray()
        self.tutorialLabel.font = UIFont.jsH3WithWeight(.Normal)
        self.tutorialLabel.numberOfLines = 0
        self.tutorialLabel.textAlignment = .Center

        self.addSubview(self.tutorialLabel)
    }

    func setupConstraints() {
        let views:[String:AnyObject] = [
            "video" : self.videoPlayerView,
            "text" : self.tutorialLabel
        ]

        self.autolayoutConstraints.appendContentsOf(
            NSLayoutConstraint.constraintsWithVisualFormat(
                "V:|-marginTop-[video]-marginBottom-[text(text@750)]-|",
                options: .AlignAllCenterX,
                metrics: self.metrics,
                views: views
            )
        )

        self.autolayoutConstraints.appendContentsOf(
            NSLayoutConstraint.constraintsWithVisualFormat(
                "H:|-marginLeft-[video]-marginRight-|",
                options: NSLayoutFormatOptions(),
                metrics: self.metrics,
                views: views
            )
        )

        self.autolayoutConstraints.appendContentsOf(
            NSLayoutConstraint.constraintsWithVisualFormat(
                "H:|-marginLeft-[text]-marginRight-|",
                options: NSLayoutFormatOptions(),
                metrics: self.metrics,
                views: views
            )
        )
    }







    // MARK: video setup
    func setVideo(url:NSURL) {
        self.tutorialVideoPlayer = AVPlayer(URL: url)

        self.videoPlayerView.player = self.tutorialVideoPlayer

        let playerLayer:AVPlayerLayer = self.videoPlayerView.layer as! AVPlayerLayer
        playerLayer.frame = self.videoPlayerView.frame
        playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
    }

    func playVideo() {
        let playerLayer = self.videoPlayerView.layer as! AVPlayerLayer

        if playerLayer.readyForDisplay {
            self.tutorialVideoPlayer.play()
        } else {
            print("Player not ready to play")
        }
    }

    func pauseVideo() {
        self.tutorialVideoPlayer.pause()
    }







    // MARK: layout hack
    override func layoutSubviews() {
        super.layoutSubviews()

        self.tutorialLabel.preferredMaxLayoutWidth = CGRectGetWidth(self.tutorialLabel.bounds)

        super.layoutSubviews()
    }
}

在我的视图控制器中,我设置了UICollectionViewCell(以及我试图显示的视频的URL),如下所示:

let cell:JSOnBoardingTutorialPageView = collectionView.dequeueReusableCellWithReuseIdentifier(self.CollectionViewCellReuseIdentifer, forIndexPath: indexPath) as! JSOnBoardingTutorialPageView

if let index = JSOnBoardingTutorialPage(rawValue: indexPath.row) {
    cell.setVideo((self.pageData[index]?.video)!)
    print(String(format: "video url: %@", (self.pageData[index]?.video)!))

    cell.tutorialText = (self.pageData[index]?.text)!
    cell.playVideo()
}

return cell

如何让我的视频显示在其容器JSAVPlayerView

1 个答案:

答案 0 :(得分:1)

我认为问题在于你永远不会调用AVPlayer的构造函数(就我从你提供的代码中看到的那样)。有一个函数func setVideo(url: NSURL),但你没有调用这个函数。