SwiftUI中点击调整字体大小时AVPlayer视频播放被重置问题咨询
问题原因
你当前的实现中,AVPlayer实例直接写在VideoPlayer的构造参数里,属于body计算属性的执行逻辑。只要@State包裹的fontSize属性发生变化,就会触发整个TEST视图重绘,每次重绘都会创建一个新的AVPlayer实例,自然会导致视频停止、重新加载播放。
解决方案
把AVPlayer实例用@State包装为视图的持久化属性,只会在视图第一次创建的时候初始化一次,后续视图重绘不会重复生成新的实例,视频播放就不会被打断。修改后的完整代码如下:
import SwiftUI import AVKit struct TEST: View { @State private var tapped: Bool = false @State private var draggedOffset = CGSize.zero @State private var fontSize: CGFloat = 20 // 调整字号用的状态 // 持久化持有AVPlayer实例,仅初始化一次 @State private var player = AVPlayer(url: URL(string: "http://www.unisonprinting.com/0celot/dune/dune.mp4")!) var body: some View { VStack { // 直接使用已创建好的player实例 VideoPlayer(player: player) .aspectRatio(3/2, contentMode: .fit) Text("VIDEO TITLE") .foregroundColor(.white) .font(.system(size: fontSize)) .onTapGesture { if fontSize < 44 { fontSize += 12 } else { fontSize = 20 } } } // 可选扩展:视图加载完成后自动播放,不需要可以删除这段 .onAppear { player.play() } } }
新手注意事项
- SwiftUI的
body是计算属性,只要监听的状态发生变化就会重新计算,不要在body内部执行初始化实例、网络请求、大量计算这类操作,否则会重复执行、产生意料之外的问题。 - 需要在视图生命周期内持久存在的实例,要用
@State、@StateObject这类属性包装器包裹,作为视图的存储属性。
内容的提问来源于stack exchange,提问作者Rene Robles
相关产品推荐
相关产品推荐

