为什么我的视频没有显示在我使用 AVPlayer 的滚动视图中的单元格中
Why aren't my videos showing in cells in my scroll view with AVPlayer
我知道我的代码目前效率不高,我只是希望它在优化之前真正起作用。
基本上我有一个函数 FeaturedPostsManager.shared.getFeaturedPosts
从我的服务器获取视频并将其存储在应用程序的缓存中并将本地 url 存储到视频中。在我的代码中,我为两个不同的视频做了两次,所以我有两个 url 用于两个不同的视频。然后我将它们 urls 添加到我的自定义数据数组中,以便我的滚动视图展开每个单元格并将其各自的视频添加到它的单元格(例如,视频一到单元格一,视频二到单元格二)到 AVPlayer .没有抛出任何错误,只是没有显示任何内容,并向我提供了这条消息:
The behavior of the UICollectionViewFlowLayout is not defined because:
2020-01-07 09:48:05.095012+0000 Clipify[9131:368986] the item height must be less than the
height of the UICollectionView minus the section insets top and bottom values, minus the
content insets top and bottom values.
2020-01-07 09:48:05.095574+0000 Clipify[9131:368986] The relevant UICollectionViewFlowLayout
instance is <UICollectionViewFlowLayout: 0x7f8be8525c20>, and it is attached to
<UICollectionView: 0x7f8be9063a00; frame = (16 150; 343 171.667); clipsToBounds = YES;
gestureRecognizers = <NSArray: 0x600003f4c1e0>; layer = <CALayer: 0x60000319b100>;
contentOffset: {0, 0}; contentSize: {0, 0}; adjustedContentInset: {0, 0, 0, 0}; layout:
<UICollectionViewFlowLayout: 0x7f8be8525c20>; dataSource: <Clipify.HomeViewController:
0x7f8be850c240>>.
我不知道这是否意味着什么,但这是我的完整代码:
import UIKit
import AVKit
import Firebase
struct CustomData {
var title: String
var image: UIImage
var url: String
}
var videoURL = ""
class HomeViewController: UIViewController {
var itemOne: String?
var itemTwo: String?
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(collectionView)
collectionView.backgroundColor = .white
collectionView.topAnchor.constraint(equalTo: view.topAnchor, constant: 150).isActive = true
collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16).isActive = true
collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16).isActive = true
collectionView.heightAnchor.constraint(equalTo: collectionView.widthAnchor, multiplier: 0.5).isActive = true
collectionView.delegate = self
collectionView.dataSource = self
getPosts()
}
func getPosts(){
FeaturedPostsManager.shared.getFeaturedPosts(index: 0, completion: { url in
if url != nil{
self.itemOne = url!
print(self.itemOne)
}else{
print("error")
}
})
FeaturedPostsManager.shared.getFeaturedPosts(index: 1, completion: { url in
if url != nil{
self.itemTwo = url!
print(self.itemTwo)
}else{
print("error")
}
})
}
var data: [CustomData] {
return [
CustomData(title: "Test", image: #imageLiteral(resourceName: "ss-1"), url: itemOne!),
CustomData(title: "Test2", image: #imageLiteral(resourceName: "done-button"), url: itemTwo!)
]
}
fileprivate let collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.translatesAutoresizingMaskIntoConstraints = false
cv.register(CustomCell.self, forCellWithReuseIdentifier: "cell")
return cv
}()
}
extension HomeViewController: UICollectionViewDelegateFlowLayout, UICollectionViewDataSource{
public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.frame.width, height: collectionView.frame.width)
}
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return data.count
}
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CustomCell
cell.data = self.data[indexPath.row]
return cell
}
}
class CustomCell: UICollectionViewCell{
var data: CustomData?{
didSet{
guard let data = data else { return }
bg.image = data.image
}
}
override init(frame: CGRect) {
super.init(frame: frame)
if let unwrappedURLString = data?.url, let url = URL(string: unwrappedURLString) {
let player = AVPlayer(url: url)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = contentView.bounds
contentView.layer.addSublayer(playerLayer)
player.play()
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
您需要在此处重新加载
FeaturedPostsManager.shared.getFeaturedPosts(index: 0, completion: { url in
if url != nil{
self.itemOne = url!
print(self.itemOne)
DispatchQueue.main.async { self.collectionView.reloadData() }
}else{
print("error")
}
})
FeaturedPostsManager.shared.getFeaturedPosts(index: 1, completion: { url in
if url != nil{
self.itemTwo = url!
print(self.itemTwo)
DispatchQueue.main.async { self.collectionView.reloadData() }
}else{
print("error")
}
})
override init(frame: CGRect) {
被调用一次。所以添加
func reload() {
if let unwrappedURLString = data?.url, let url = URL(string: unwrappedURLString) {
let player = AVPlayer(url: url)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = contentView.bounds
contentView.layer.addSublayer(playerLayer)
player.play()
}
}
然后
var data: CustomData?{
didSet{
guard let data = data else { return }
bg.image = data.image
self.reload()
}
}
我知道我的代码目前效率不高,我只是希望它在优化之前真正起作用。
基本上我有一个函数 FeaturedPostsManager.shared.getFeaturedPosts
从我的服务器获取视频并将其存储在应用程序的缓存中并将本地 url 存储到视频中。在我的代码中,我为两个不同的视频做了两次,所以我有两个 url 用于两个不同的视频。然后我将它们 urls 添加到我的自定义数据数组中,以便我的滚动视图展开每个单元格并将其各自的视频添加到它的单元格(例如,视频一到单元格一,视频二到单元格二)到 AVPlayer .没有抛出任何错误,只是没有显示任何内容,并向我提供了这条消息:
The behavior of the UICollectionViewFlowLayout is not defined because:
2020-01-07 09:48:05.095012+0000 Clipify[9131:368986] the item height must be less than the
height of the UICollectionView minus the section insets top and bottom values, minus the
content insets top and bottom values.
2020-01-07 09:48:05.095574+0000 Clipify[9131:368986] The relevant UICollectionViewFlowLayout
instance is <UICollectionViewFlowLayout: 0x7f8be8525c20>, and it is attached to
<UICollectionView: 0x7f8be9063a00; frame = (16 150; 343 171.667); clipsToBounds = YES;
gestureRecognizers = <NSArray: 0x600003f4c1e0>; layer = <CALayer: 0x60000319b100>;
contentOffset: {0, 0}; contentSize: {0, 0}; adjustedContentInset: {0, 0, 0, 0}; layout:
<UICollectionViewFlowLayout: 0x7f8be8525c20>; dataSource: <Clipify.HomeViewController:
0x7f8be850c240>>.
我不知道这是否意味着什么,但这是我的完整代码:
import UIKit
import AVKit
import Firebase
struct CustomData {
var title: String
var image: UIImage
var url: String
}
var videoURL = ""
class HomeViewController: UIViewController {
var itemOne: String?
var itemTwo: String?
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(collectionView)
collectionView.backgroundColor = .white
collectionView.topAnchor.constraint(equalTo: view.topAnchor, constant: 150).isActive = true
collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16).isActive = true
collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16).isActive = true
collectionView.heightAnchor.constraint(equalTo: collectionView.widthAnchor, multiplier: 0.5).isActive = true
collectionView.delegate = self
collectionView.dataSource = self
getPosts()
}
func getPosts(){
FeaturedPostsManager.shared.getFeaturedPosts(index: 0, completion: { url in
if url != nil{
self.itemOne = url!
print(self.itemOne)
}else{
print("error")
}
})
FeaturedPostsManager.shared.getFeaturedPosts(index: 1, completion: { url in
if url != nil{
self.itemTwo = url!
print(self.itemTwo)
}else{
print("error")
}
})
}
var data: [CustomData] {
return [
CustomData(title: "Test", image: #imageLiteral(resourceName: "ss-1"), url: itemOne!),
CustomData(title: "Test2", image: #imageLiteral(resourceName: "done-button"), url: itemTwo!)
]
}
fileprivate let collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.translatesAutoresizingMaskIntoConstraints = false
cv.register(CustomCell.self, forCellWithReuseIdentifier: "cell")
return cv
}()
}
extension HomeViewController: UICollectionViewDelegateFlowLayout, UICollectionViewDataSource{
public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.frame.width, height: collectionView.frame.width)
}
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return data.count
}
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CustomCell
cell.data = self.data[indexPath.row]
return cell
}
}
class CustomCell: UICollectionViewCell{
var data: CustomData?{
didSet{
guard let data = data else { return }
bg.image = data.image
}
}
override init(frame: CGRect) {
super.init(frame: frame)
if let unwrappedURLString = data?.url, let url = URL(string: unwrappedURLString) {
let player = AVPlayer(url: url)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = contentView.bounds
contentView.layer.addSublayer(playerLayer)
player.play()
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
您需要在此处重新加载
FeaturedPostsManager.shared.getFeaturedPosts(index: 0, completion: { url in
if url != nil{
self.itemOne = url!
print(self.itemOne)
DispatchQueue.main.async { self.collectionView.reloadData() }
}else{
print("error")
}
})
FeaturedPostsManager.shared.getFeaturedPosts(index: 1, completion: { url in
if url != nil{
self.itemTwo = url!
print(self.itemTwo)
DispatchQueue.main.async { self.collectionView.reloadData() }
}else{
print("error")
}
})
override init(frame: CGRect) {
被调用一次。所以添加
func reload() {
if let unwrappedURLString = data?.url, let url = URL(string: unwrappedURLString) {
let player = AVPlayer(url: url)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = contentView.bounds
contentView.layer.addSublayer(playerLayer)
player.play()
}
}
然后
var data: CustomData?{
didSet{
guard let data = data else { return }
bg.image = data.image
self.reload()
}
}