目前,我有一个快速文件,在其中使用我也创建的数据模型具有三个硬编码值,该数据模型带有标题,图像和url(此刻我仅显示图像)。我了解如何更改每个单元格以显示其应在滚动视图中显示的图像:
import UIKit
import AVKit
import Firebase
struct CustomData {
var title: String
var image: UIImage
var url: String
}
var videoURL = ""
var array = [String]()
class HomeViewController: UIViewController {
var fileArray:Array<Any>?
fileprivate let data = [
CustomData(title: "Test", image: #imageLiteral(resourceName: "ss-1"), url: "test.com"),
CustomData(title: "Test2", image: #imageLiteral(resourceName: "done-button"), url: "test.com"),
CustomData(title: "Test2", image: #imageLiteral(resourceName: "notificationIcon"), url: "test.com")
]
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
}()
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
array = fileArray as! [String]
}
}
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
}
}
fileprivate let bg: UIImageView = {
let iv = UIImageView()
iv.image = #imageLiteral(resourceName: "splash_icon")
iv.translatesAutoresizingMaskIntoConstraints = false
iv.contentMode = .scaleAspectFill
iv.clipsToBounds = true
iv.layer.cornerRadius = 10
return iv
}()
override init(frame: CGRect) {
super.init(frame: frame)
// let player = AVPlayer(url: URL(string: videoURL)!)
// let playerLayer = AVPlayerLayer(player: player)
// playerLayer.frame = contentView.bounds
// contentView.layer.addSublayer(playerLayer)
// player.play()
contentView.addSubview(bg)
bg.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
bg.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
bg.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
bg.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
上面的代码成功地在滚动视图中的相应单元格中显示了我在data
数组中指定的所有三个图像。我有一个数组,其中包含10个字符串,这些字符串都是设备上本地不同视频的唯一URL(所有大小均相同)。通过更改此部分,我设法显示了视频:
override init(frame: CGRect) {
super.init(frame: frame)
// let player = AVPlayer(url: URL(string: videoURL)!)
// let playerLayer = AVPlayerLayer(player: player)
// playerLayer.frame = contentView.bounds
// contentView.layer.addSublayer(playerLayer)
// player.play()
contentView.addSubview(bg)
bg.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
bg.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
bg.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
bg.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
}
对此:
override init(frame: CGRect) {
super.init(frame: frame)
let player = AVPlayer(url: URL(string: videoURL)!)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = contentView.bounds
contentView.layer.addSublayer(playerLayer)
player.play()
// contentView.addSubview(bg)
// bg.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
// bg.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
// bg.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
// bg.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
}
但是显然,一个视频中包含硬编码,并且相同的视频将显示在滚动视图的所有单元格中。因此,我将如何做与UIImageView相同的工作:
var data: CustomData?{
didSet{
guard let data = data else { return }
bg.image = data.image
}
}
fileprivate let bg: UIImageView = {
let iv = UIImageView()
iv.image = #imageLiteral(resourceName: "splash_icon")
iv.translatesAutoresizingMaskIntoConstraints = false
iv.contentMode = .scaleAspectFill
iv.clipsToBounds = true
iv.layer.cornerRadius = 10
return iv
}()
但是使用AVPlayer或其他视频播放器才能使所有单元动态显示不同的视频,我知道我必须更改数据模型并从数组中获取值,等等,我似乎找不到办法与我对图像视图所做的相同。
谢谢,
内森
[查看代码后,由于要在此代码块中将data.image
设置为UIImageView
,因此您设法获得了所需的图像显示>
var data: CustomData?{ didSet{ guard let data = data else { return } bg.image = data.image } }
如果要为每个单元格播放
data
中列出的视频,则需要使用data.url
初始化AVP播放器。
不想浪费太多的代码,可以尝试的是这样:
let player = AVPlayer(url: URL(string: data?.url)!) // use the URL from your data models here
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = contentView.bounds
contentView.layer.addSublayer(playerLayer)
player.play()