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

SwiftUI: Play video only if it's in the centre of the screen

您好,我正在制作仅在视频位于视图中心时播放视频的应用。我已经设法在滚动视图中获得位置,但我无法将其与播放视频结合起来。

这是我的主要观点:

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: -[=10=].frame(in: .named("scroll")).origin.y)
            })
            
        }.onPreferenceChange(ViewOffsetKey.self) {
            position = [=10=]
        }
        .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设为Binding以使VideoViewAVPlayerControllerRepresented中的更改生效,然后相应地添加这些代码

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