Установить размер AVPlayer/AVPlayerLayer с помощью AutoLayout?

Я пытаюсь установить размер/кадр видео, которое я показываю в своем представлении, используя 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 не обновляет значение, как я сначала подумал.

Если я устанавливаю размер playerLayer.frame вручную с помощью CGRect, все работает как надо. Но я хочу использовать AutoLayout.

Итак, как я могу установить размер AvPlayerLayer с помощью AutoLayout?


person eivindml    schedule 05.01.2018    source источник


Ответы (1)


Do:

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
    }
}
person Brandon    schedule 05.01.2018
comment
Спасибо. Это сработало. Мне также пришлось добавить функцию layoutSubviews(). И установите его на self.videoView.bounds. Почему это работает при установке в функции layoutSubviews(), но не в методе init()? Почему bounds видеопросмотра все еще (0.0, 0.0, 0.0, 0.0) на данный момент? - person eivindml; 05.01.2018
comment
@эйвиндмл; Когда вы создаете представление, оно еще не выложено до тех пор, пока не будет добавлено в другое представление или viewController и готово к отображению. По этой причине, если вы явно не установите фрейм, то фрейм по умолчанию будет .zero. При использовании автоматического макета он вызовет layoutSubviews для завершения обновления дочерних элементов представления. На данный момент ваше представление выложено, и вы можете использовать его границы. Примечание: НЕ используйте его фрейм, потому что фрейм может быть изменен анимацией и преобразованиями и даст вам неправильную информацию: D Рад, что это сработало. - person Brandon; 05.01.2018