You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 13:24:04