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
以使VideoView
和AVPlayerControllerRepresented
中的更改生效,然后相应地添加这些代码
player.play() // to play
player.stop() // to stop
您好,我正在制作仅在视频位于视图中心时播放视频的应用。我已经设法在滚动视图中获得位置,但我无法将其与播放视频结合起来。
这是我的主要观点:
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
以使VideoView
和AVPlayerControllerRepresented
中的更改生效,然后相应地添加这些代码
player.play() // to play
player.stop() // to stop