我正在尝试显示一个循环视频,然后允许用户点击一个按钮以显示下一个或上一个循环视频。
为什么@Binding不更新此内容?正确的/最佳的方法是什么?
我正在使用UIViewRepresentable。这是我的代码...
struct Player: UIViewRepresentable {
var videoFileNames: [String]
@Binding var currentItem: Int
func makeUIView(context: Context) -> UIView {
return PlayerView(frame: .zero, videoFileNames: videoFileNames, currentItem: currentItem)
}
func updateUIView(_ uiView: UIView, context: Context) {
}
}
class PlayerView: UIView {
private let playerLayer = AVPlayerLayer()
private var playerLooper: AVPlayerLooper?
init(frame: CGRect, videoFileNames: [String], currentItem: Int) {
super.init(frame: frame)
var playerItems = [AVPlayerItem]()
let player = AVQueuePlayer(items: playerItems)
for videoFileName in videoFileNames {
guard let path = Bundle.main.path(forResource: videoFileName, ofType: "mp4") else {
return
}
let videoURL = NSURL(fileURLWithPath: path)
let playerItem = AVPlayerItem(url: videoURL as URL)
playerItems.append(playerItem)
}
playerLooper = AVPlayerLooper(player: player, templateItem: playerItems[currentItem])
player.volume = 0
player.play()
playerLayer.player = player
playerLayer.videoGravity = .resizeAspectFill
layer.addSublayer(playerLayer)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override func layoutSubviews() {
super.layoutSubviews()
playerLayer.frame = bounds
}
}
@Binding
中的更改仅导致调用updateUIView
,因此您需要调整以下内容(使用伪代码,从头开始)
struct Player: UIViewRepresentable {
var videoFileNames: [String]
@Binding var currentItem: Int
private var playerView: PlayerView!
func makeUIView(context: Context) -> UIView {
let view = PlayerView(frame: .zero, videoFileNames: videoFileNames, currentItem: currentItem)
self.playerView = view
return view
}
func updateUIView(_ uiView: UIView, context: Context) {
self.playerView.currentItem = currentItem // update player !!
}
}
class PlayerView: UIView {
var currentItem: Int {
didSet {
// .. refresh here internal player
}
}
init(frame: CGRect, videoFileNames: [String], currentItem: Int) {
super.init(frame: frame)
self.currentItem = currentItem
var playerItems = [AVPlayerItem]()
// .. other code