Ios 带其他视图的UITableViewCell内的AVPlayer自动布局
我有一个UITableViewCell,它有一个UILabel和一个AVPlayer,可以播放我需要实现的在线视频。问题是AVPlayer无法使用自动布局正确显示视频 我相信对于混合约束和框架布局,有一些方法可以实现UIView。我认为这个问题还有很多:视频没有加载到init上这一事实似乎存在问题 UITableViewCellIos 带其他视图的UITableViewCell内的AVPlayer自动布局,ios,swift,uitableview,autolayout,avplayer,Ios,Swift,Uitableview,Autolayout,Avplayer,我有一个UITableViewCell,它有一个UILabel和一个AVPlayer,可以播放我需要实现的在线视频。问题是AVPlayer无法使用自动布局正确显示视频 我相信对于混合约束和框架布局,有一些方法可以实现UIView。我认为这个问题还有很多:视频没有加载到init上这一事实似乎存在问题 UITableViewCell import UIKit import AVKit import AVFoundation class PlayerView: UIView { var pl
import UIKit
import AVKit
import AVFoundation
class PlayerView: UIView {
var player: AVPlayer? {
get {
return playerLayer.player
}
set {
playerLayer.videoGravity = .resizeAspect
playerLayer.player = newValue
}
}
var playerLayer: AVPlayerLayer {
return layer as! AVPlayerLayer
}
override static var layerClass: AnyClass {
return AVPlayerLayer.self
}
}
class CustomTableCell: UITableViewCell {
let titleView = UILabel()
let containerView = UIView()
let playerView = PlayerView()
required init?(coder aDecoder: NSCoder) {super.init(coder: aDecoder)}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
titleView.text = "Title"
titleView.translatesAutoresizingMaskIntoConstraints = false
contentView.clipsToBounds = true
containerView.clipsToBounds = true
contentView.addSubview(containerView)
containerView.translatesAutoresizingMaskIntoConstraints = false
//contentView.layoutMargins = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
var lg = contentView.layoutMarginsGuide
NSLayoutConstraint.activate([
containerView.topAnchor.constraint(equalTo: lg.topAnchor),
containerView.leadingAnchor.constraint(equalTo: lg.leadingAnchor),
containerView.trailingAnchor.constraint(equalTo: lg.trailingAnchor),
containerView.bottomAnchor.constraint(equalTo: lg.bottomAnchor)
])
containerView.addSubview(titleView)
containerView.layoutMargins = UIEdgeInsets(top: 15, left: 17, bottom: 15, right: 17)
lg = containerView.layoutMarginsGuide
playerView.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(playerView)
NSLayoutConstraint.activate([
titleView.topAnchor.constraint(equalTo: lg.topAnchor),
titleView.leadingAnchor.constraint(equalTo: lg.leadingAnchor),
titleView.trailingAnchor.constraint(equalTo: lg.trailingAnchor),
// titleView.bottomAnchor.constraint(equalTo: lg.bottomAnchor),
playerView.topAnchor.constraint(equalTo: titleView.bottomAnchor),
playerView.leadingAnchor.constraint(equalTo: lg.leadingAnchor),
playerView.trailingAnchor.constraint(equalTo: lg.trailingAnchor),
playerView.bottomAnchor.constraint(equalTo: lg.bottomAnchor)
])
}
}
我已经在我的视图控制器中设置了UITableView,但主要问题是UITableViewDataSource cellForRowAt:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReuseableCell(withIdentifier: "cell") as! CustomTableCell
let url = NSURL(string: "https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
let avPlayer = AVPlayer(url: url! as URL)
cell.playerView.playerLayer.player = avPlayer
return cell
}
但我没有看到视频。很明显,有一个类似willLayoutSubviews之类的函数,但是我如何打破标题视图的约束,用AVPlayerLayer或类似的东西来约束,这样我就可以看到视频了
一般来说,我如何看到AVPlayer或自定义UITableViewCell中具有其他自动布局视图的任何播放器
编辑1:@ugur给出的答案是正确的,因为AVPlayer需要调整大小。使用leadngAnchor和trailingAnchor扩展视图无法解决此问题,因为仅扩展了当前视图的大小
使用centerXAnchor、widthAnchor和heightAnchor将有效。centerXAnchor将使您的播放器在视图中居中。您需要告诉autolayout如何计算playerView高度。 您可以尝试以下选项:
playerView.heightAnchor.constraint(equalToConstant: 100)
playerView.heightAnchor.constraint(equalTo: playerView.widthAnchor, multiplier: 1.0)
playerView.heightAnchor.constraint(equalToConstant: 100)
playerView.heightAnchor.constraint(equalTo: playerView.widthAnchor, multiplier: 1.0)
不要在
cellFor
中创建AVPlayer
,而是在cell init或awakeFromNib
中创建(如果使用了脚本)。因此,AVPlayer
也可以重用。只需使用新url或playerItem
重置设置即可。您也可以根据您的情况使用播放或暂停。但是不要每次调用cellFor
时都重新创建AVPlayer
。因此,您的主要问题是无法在单元格内看到播放机。我修改了你们的一些代码,然后它也显示和播放视频
注意:这是非常基本的代码,我相信您将能够根据您的要求进一步改进它
您的PlayerView
保持不变,更改如下。我添加了新的方法configureFor
,它将只获取url作为参数和播放器的设置
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomTableCell
let url = URL(string: "https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
cell.configureFor(url!)
return cell
}
以下是您的单元格代码。
在这里,我将UI设置代码移动到一个公共函数commonInit()
,然后按如下方式使用它
class CustomTableCell: UITableViewCell {
let titleView = UILabel()
let containerView = UIView()
let playerView = PlayerView()
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
commonInit()
}
func commonInit() {
titleView.text = "Title"
titleView.translatesAutoresizingMaskIntoConstraints = false
contentView.clipsToBounds = true
containerView.clipsToBounds = true
containerView.backgroundColor = .orange
contentView.addSubview(containerView)
containerView.translatesAutoresizingMaskIntoConstraints = false
//contentView.layoutMargins = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
var lg = contentView.layoutMarginsGuide
NSLayoutConstraint.activate([
containerView.topAnchor.constraint(equalTo: lg.topAnchor),
containerView.leadingAnchor.constraint(equalTo: lg.leadingAnchor),
containerView.trailingAnchor.constraint(equalTo: lg.trailingAnchor),
containerView.bottomAnchor.constraint(equalTo: lg.bottomAnchor)
])
containerView.addSubview(titleView)
containerView.layoutMargins = UIEdgeInsets(top: 15, left: 17, bottom: 15, right: 17)
lg = containerView.layoutMarginsGuide
playerView.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(playerView)
NSLayoutConstraint.activate([
titleView.topAnchor.constraint(equalTo: lg.topAnchor),
titleView.leadingAnchor.constraint(equalTo: lg.leadingAnchor),
titleView.trailingAnchor.constraint(equalTo: lg.trailingAnchor),
// titleView.bottomAnchor.constraint(equalTo: lg.bottomAnchor),
playerView.topAnchor.constraint(equalTo: titleView.bottomAnchor),
playerView.leadingAnchor.constraint(equalTo: lg.leadingAnchor),
playerView.trailingAnchor.constraint(equalTo: lg.trailingAnchor),
playerView.bottomAnchor.constraint(equalTo: lg.bottomAnchor)
])
}
func configureFor(_ url: URL) {
let avPlayer = AVPlayer(url: url)
self.playerView.playerLayer.player = avPlayer
self.playerView.playerLayer.player?.play()
}
}
你能分享一些屏幕截图吗?@Niraj_iOS我只看到文本。视频不会出现。事实上,即使它做了它没有做的,如果用户重新定位了设备,然后视频就会变成一场灾难。你可以将
ui视图
放在情节提要中,并在该视图中添加播放器programatically@Yoomama请看下面的答案,我希望能解决您的问题。@Yoomama您是否检查了下面的答案?如果我同时设置了高度和宽度锚点(连同顶部和底部锚(idk??),视频会失真吗?另外,我把它放在cellFor中,因为我正在用它链接一个服务器,需要某种索引来使用cellFor将一组数据链接到cellFor。我还能怎么做呢?你介意举个例子说明我如何在cellFor的init中而不是cellFor中实例化吗?非常缺乏经验抱歉,它不起作用。我感觉到的担心是引导anchor和trailingAnchor。知道这个UIView不是一个正常的UIView。你必须增加AVPlayer的大小,这需要高度和宽度锚。好吧,因为我在本地尝试过,它正在显示播放器,而且视频正在播放,我所做的一切在模拟器上看到的是iOS 13 iPhone 11 Pro Max上的橙色单元格。请检查@ugur给出的答案。不要粗鲁,但你的init没有什么帮助。将init移动到自定义函数中不会放大PlayerView。你需要这些锚来显示视频。在初始化后安装视频对任何视图都不起作用NL除非重新实例化视图。更改还在于如何配置单元格。请在索引路径处查看单元格中的行