我正在我的应用程序上使用包含各个
TabView
的 AVPlayer
实现 Instagram Reels 样式视图。
当我尝试将其他元素添加到我的初始列表(以模拟无限滚动)时,我得到了一个非常奇怪的效果:正如您在视频中看到的,当播放 id 98 的卷轴时,我将新卷轴添加到我的列表中并且当前播放的视频出现“闪烁”,无论上一个视频的音频是否开始。
看起来
TabView
已重新渲染,但不正确。
这是我的代码:
卷轴视图:
GeometryReader { geo in
TabView(selection: $currentReel) {
ForEach(0..<items.count, id: \.self) { i in
let reelModel = items[i]
ReelPlayerView(reel: reelModel.reel, videoPlayerModel: reelModel.videoPlayerModel, width: geo.size.width, height: geo.size.height)
.frame(width: geo.size.width)
.rotationEffect(.init(degrees: 270))
.ignoresSafeArea(.all, edges: .top)
.tag(i)
.id(i)
}
}
.id(items.count)
.rotationEffect(.init(degrees: 90))
.frame(width: geo.size.height)
.tabViewStyle(.page(indexDisplayMode: .never))
.indexViewStyle(.page(backgroundDisplayMode: .never))
.frame(maxWidth: geo.size.width)
.onChange(of: currentReel) { value in
for i in items.indices {
if i == value {
items[i].videoPlayerModel.play()
} else {
items[i].videoPlayerModel.stop()
}
}
if (currentReel == Int(items.count - 1)) {
self.items.append(contentsOf: self.items) --> here I append the new items, when I'm at the half of scrolled items
}
}
.onAppear() {
if items[currentReel].videoPlayerModel.player != nil {
items[currentReel].videoPlayerModel.play()
}
}
.onDisappear() {
items[currentReel].videoPlayerModel.pause()
}
}
.ignoresSafeArea(.all, edges: .top)
ReelPlayer视图:
CustomVideoPlayer(hls: reel.video_url!) { videoPlayer in
DispatchQueue.main.async {
videoPlayerModel.player = videoPlayer
}
}
.frame(width: width, height: height)
如何解决?
尝试删除
.id(items.count)
,因为这会导致 TabView
在更新 items
时重新渲染。
无关:
当
currentReel
更改时,您无需循环遍历整个项目。只需开始播放当前项目,并停止上一个项目:
.onChange(of: currentReel) { newValue in
if newValue > 0 {
items[newValue - 1].videoPlayerModel.stop()
}
items[newValue].videoPlayerModel.play()
let lastItem = newValue == items.count - 1
if lastItem {
items.append(contentsOf: items)
}
}