按下按钮时 Swiftui 中的 AVPLayer 会重置

AVPLayer in Swiftui resets when button is pressed

我有一个视频播放器,在它下面有一个标题文本。当您点击文本时,我会增加字体大小。但是,当您增加字体大小时,它会导致视频停止播放并重新启动。我不希望发生这种情况。我希望视频播放不受字体增加的影响。 我对 swiftUI 很陌生。

import SwiftUI

导入 AVKit

结构测试:查看{

@State private var tapped: Bool = false
@State private var draggedOffset = CGSize.zero
@State private var fontSize: CGFloat = 20 // Change Font Size

var body: some View {
    
    VStack {
        
        VideoPlayer(player: AVPlayer(url: URL(string: "http://www.unisonprinting.com/0celot/dune/dune.mp4")!))
            .aspectRatio(3/2, contentMode: .fit)
        
        Text ("VIDEO TITLE")
            .foregroundColor(.white)
            .font(.system(size: fontSize))
            .onTapGesture {
                if self.fontSize < 44 {
                    self.fontSize = self.fontSize + 12
                } else {
                    self.fontSize = 20
                }
            }
    }//V

}

}

现在,每次渲染 View 的 body,都会创建一个 new AVPlayer,导致视频停止播放并重新开始。

您可以通过将 AVPlayer 存储在 @State 变量中来避免这种情况,该变量在渲染过程中持续存在:

struct TEST: View {
    
    @State private var tapped: Bool = false
    @State private var draggedOffset = CGSize.zero
    @State private var fontSize: CGFloat = 20 // Change Font Size
    
    @State private var player = AVPlayer(url: URL(string: "https://www.unisonprinting.com/0celot/dune/dune.mp4")!)
    
    var body: some View {
        
        VStack {
            
            VideoPlayer(player: player)
                .aspectRatio(3/2, contentMode: .fit)
            
            Text ("VIDEO TITLE")
                .foregroundColor(.blue)
                .font(.system(size: fontSize))
                .onTapGesture {
                    if self.fontSize < 44 {
                        self.fontSize = self.fontSize + 12
                    } else {
                        self.fontSize = 20
                    }
                }
        }
    }
}


更新,基于评论,展示了一种可能的解决方案,即如何让 VideoPlayer 根据变化的 URL 参数加载不同的 AVPlayer

struct ContentView: View {
    
    var url : String = "https://www.unisonprinting.com/0celot/dune/dune.mp4"
    
    @State private var tapped: Bool = false
    @State private var draggedOffset = CGSize.zero
    @State private var fontSize: CGFloat = 20 // Change Font Size
    
    @State private var player : AVPlayer?
    
    var body: some View {
        
        VStack {
            if let player = player {
                VideoPlayer(player: player)
                    .aspectRatio(3/2, contentMode: .fit)
            }
            
            Text ("VIDEO TITLE")
                .foregroundColor(.blue)
                .font(.system(size: fontSize))
                .onTapGesture {
                    if self.fontSize < 44 {
                        self.fontSize = self.fontSize + 12
                    } else {
                        self.fontSize = 20
                    }
                }
        }
        .onAppear {
            setPlayerToUrl(url)
        }
        .onChange(of: url) { url in
            setPlayerToUrl(url)
        }
    }
    
    func setPlayerToUrl(_ url: String) {
        player = AVPlayer(url: URL(string: url)!)
    }
}