Почему мой объект AVMoviePlayer в моем AVPlayreLayer не будет отображаться в ячейке представления таблицы автоматического размера?
Я использую подкласс UITableViewCell, который создает один из двух подклассов UIView в зависимости от типа мультимедиа, которое показывает ячейка табличного представления - либо UIImageView, либо мой собственный подкласс UIView, который использует AVPlayerLayer. Ячейка табличного представления должна иметь размер в соответствии с режимом содержимого подкласса UIView, который является.scaleAspectFit. Мой код работает, когда мультимедиа представляет собой изображение, показываемое в UIImageView, но не когда мультимедиа представляет собой фильм, показываемый в подклассе UIView с использованием AVPlayerLayer, и в этом случае ячейка табличного представления представляет собой узкую строку. Я знаю, что фильм играет, потому что я слышу, как он играет.
Что я должен изучить, чтобы это исправить?
class MediaTableViewCell: UITableViewCell {
var mediaView: UIView!
var audioPlayer: AVAudioPlayer!
var mediaImageView: UIImageView!
var playerView: PlayerView!
var playerLooper: AVPlayerLooper!
func setMedia(mediaType: MediaType?, mediaURL: URL?) {
// mediaType and mediaURL are always both nil or both not nil.
if let mediaType = mediaType, let mediaURL = mediaURL {
mediaView?.removeFromSuperview()
switch mediaType {
case .music:
let image = UIImage(named: "audio.png")
mediaImageView = UIImageView()
mediaImageView.contentMode = .scaleAspectFit
mediaImageView.image = image
mediaView = mediaImageView
playerView = nil
audioPlayer = try? AVAudioPlayer(contentsOf: mediaURL)
audioPlayer?.play()
case .image:
let image = UIImage(contentsOfFile: mediaURL.path)
mediaImageView = UIImageView()
mediaImageView.contentMode = .scaleAspectFit
mediaImageView.image = image
mediaView = mediaImageView
playerView = nil
case .movie:
playerView = PlayerView()
playerView.contentMode = .scaleAspectFit
mediaView = playerView
mediaImageView = nil
let playerItem = AVPlayerItem(url: mediaURL)
playerView.player = AVQueuePlayer()
playerLooper = AVPlayerLooper(player: playerView.player!, templateItem: playerItem)
playerView.player!.play()
}
} else {
let image = UIImage(named: "vision.png")!
mediaImageView = UIImageView()
mediaImageView.contentMode = .scaleAspectFit
mediaImageView.image = image
mediaView = mediaImageView
playerView = nil
}
mediaView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(mediaView)
NSLayoutConstraint(item: mediaView, attribute: .leading, relatedBy: .equal, toItem: contentView, attribute: .leadingMargin, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: mediaView, attribute: .trailing, relatedBy: .equal, toItem: contentView, attribute: .trailingMargin, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: mediaView, attribute: .top, relatedBy: .equal, toItem: contentView, attribute: .topMargin, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: mediaView, attribute: .bottom, relatedBy: .equal, toItem: contentView, attribute: .bottomMargin, multiplier: 1, constant: 0).isActive = true
contentView.setNeedsLayout()
contentView.layoutIfNeeded()
contentView.setNeedsDisplay()
}
}
class PlayerView: UIView {
var player: AVQueuePlayer? {
get {
return playerLayer.player as? AVQueuePlayer
}
set {
playerLayer.player = newValue
}
}
var playerLayer: AVPlayerLayer {
return layer as! AVPlayerLayer
}
// Override UIView property
override static var layerClass: AnyClass {
return AVPlayerLayer.self
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch indexPath.section {
...
case 2:
let cell = tableView.dequeueReusableCell(withIdentifier: "mediaCell") as! MediaTableViewCell
tableView.beginUpdates()
if let detailItem = detailItem {
cell.setMedia(mediaType: detailItem.mediaType, mediaURL: detailItem.mediaURL)
} else {
cell.setMedia(mediaType: nil, mediaURL: nil)
}
tableView.endUpdates()
tableView.setNeedsLayout()
tableView.layoutIfNeeded()
tableView.setNeedsDisplay()
view.setNeedsLayout()
view.layoutIfNeeded()
view.setNeedsDisplay()
return cell
default:
fatalError()
}
fatalError()
}