SwiftUI:仅当视频位于屏幕中央时,才播放视频



嗨,正在制作仅播放视频的应用程序,如果它位于视图的中心。我已经设法在滚动视图中获得了该位置,但我无法将其与播放视频结合起来。

这是我的主要观点:

struct MainView: View {
@State var position = 0.0
var body: some View {
ScrollView {
ForEach(videos){ video in
VideoView(player: video.player)
.onChange(of: position) { pos in
if pos > -50 && pos < 400 {
print("Play video")
}else {
print("Stop video")
}
}
}
.background(GeometryReader {
Color.clear.preference(key: ViewOffsetKey.self, value: -$0.frame(in: .named("scroll")).origin.y)
})

}.onPreferenceChange(ViewOffsetKey.self) {
position = $0
}
.coordinateSpace(name: "scroll")
.padding()
}
}

这是我的视频模型:

struct VideoModel: Identifiable {
var id = UUID()
var number: Int
var player: AVPlayer
}

这是视频阵列:

let videos = [
VideoModel(number: 1, player: AVPlayer(url: URL(fileURLWithPath: Bundle.main.path(forResource: "video", ofType: "mp4")!))),
VideoModel(number: 3, player: AVPlayer(url: URL(fileURLWithPath: Bundle.main.path(forResource: "video", ofType: "mp4")!))),
VideoModel(number: 4, player: AVPlayer(url: URL(fileURLWithPath: Bundle.main.path(forResource: "video", ofType: "mp4")!))),
VideoModel(number: 5, player: AVPlayer(url: URL(fileURLWithPath: Bundle.main.path(forResource: "video", ofType: "mp4")!)))
]

这些是处理视频播放器和首选项键的结构:

struct ViewOffsetKey: PreferenceKey {
typealias Value = CGFloat
static var defaultValue = CGFloat.zero
static func reduce(value: inout Value, nextValue: () -> Value) {
value += nextValue()
}
}
struct VideoView: View {
var player: AVPlayer
var body: some View {
AVPlayerControllerRepresented(player: player)
.frame(height: height)
}
}
struct AVPlayerControllerRepresented : UIViewControllerRepresentable {
var player : AVPlayer

func makeUIViewController(context: Context) -> AVPlayerViewController {
let controller = AVPlayerViewController()
controller.player = player
controller.showsPlaybackControls = false
return controller
}

func updateUIViewController(_ uiViewController: AVPlayerViewController, context: Context) {

}
}

请帮忙,我将不胜感激。

首先,您需要使AVPlayer成为VideoViewAVPlayerControllerRepresented中的更改生效的Binding,然后相应地添加这些代码片段

player.play() // to play
player.stop() // to stop

最新更新