【问题标题】:Set AVPlayer/AVPlayerLayer size using AutoLayout?使用 AutoLayout 设置 AVPlayer/AVPlayerLayer 大小?
【发布时间】:2018-01-05 15:45:19
【问题描述】:

我正在尝试使用 AutoLayout 设置我在视图中显示的视频的大小/帧。但我不知道如何正确地做到这一点。这是我的观点的代码:

import UIKit
import AVKit

class VideoMeetingView: UIView {

    lazy var playerLayer: AVPlayerLayer = {
        let layer = AVPlayerLayer()
        return layer
    }()

    private lazy var videoView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = .blue
        return view
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.backgroundColor = #colorLiteral(red: 0.5725490451, green: 0, blue: 0.2313725501, alpha: 1)
        self.addSubviewsAndConstraints()

        playerLayer.frame = videoView.bounds
        videoView.layer.addSublayer(playerLayer)
    }

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

    private func addSubviewsAndConstraints() {
        self.addSubview(videoView)

        videoView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
        videoView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
        videoView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
        videoView.heightAnchor.constraint(equalToConstant: 600).isActive = true
    }

}

如果我打印出videoView.bounds 的值,它只是(0, 0, 0, 0),所以我猜 AutoLayout 不会像我最初想的那样更新值。

如果我使用CGRect 手动设置playerLayer.frame 的大小,则一切正常。但我想使用 AutoLayout。

那么如何使用 AutoLayout 设置 AvPlayerLayer 的大小?

【问题讨论】:

    标签: ios swift avplayer avplayerlayer


    【解决方案1】:

    做:

    self.playerLayer = {
       let layer = AVPlayerLayer(player: self.player)
        layer.videoGravity = .resizeAspect
        layer.needsDisplayOnBoundsChange = true
        return layer
    }()
    

    当其父级的边界发生变化时,这会导致图层调整宽高比。

    另外,您可能必须添加:

    override func layoutSubviews() {
        super.layoutSubviews()
    
        self.playerLayer.frame = self.bounds
    }
    

    所以无论如何它都有正确的框架..

    另一种选择是使AVPlayerLayer 成为UIView 本身的实际层,而不是子层:

    class VideoView : UIView
    {
        override var layer: CALayer {
            return AVPlayerLayer.class
        }
    }
    

    【讨论】:

    • 谢谢。有效。我还必须添加 layoutSubviews() 函数。并将其设置为self.videoView.bounds。为什么在 layoutSubviews() 函数中设置时它起作用,但在 init() 方法中不起作用?为什么此时videoView的bounds还是(0.0, 0.0, 0.0, 0.0)
    • @eivindml;当您创建一个视图时,它还没有被布局,直到它被添加到另一个视图或 viewController 并准备好被显示。因此,除非您明确设置框架,否则默认情况下框架将为.zero。使用自动布局时,它将调用layoutSubviews 来完成对视图子项的更新。此时,您的视图已经布局,您可以使用它的边界。注意:不要使用它的框架,因为框架可以通过动画和转换来修改,并且会给你错误的信息:D 很高兴它起作用了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-25
    • 1970-01-01
    • 2015-10-02
    • 2012-03-29
    • 2014-10-06
    • 1970-01-01
    • 2015-05-28
    相关资源
    最近更新 更多