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

SwiftUI中如何预览相册选中的视频?解决初始化未使用报错

解决SwiftUI视频预览不显示及"Result of 'VideoPlayer' initializer is unused"错误

问题根源

  1. 未处理PhotosPicker选中视频后的URL赋值逻辑,导致视频URL始终为nil,VideoPlayer从未被创建。
  2. VideoPlayer缺少布局约束,SwiftUI无法确定其显示尺寸,导致视图无法正常渲染,触发"initializer is unused"错误。
  3. 直接在VideoPlayer中初始化AVPlayer,播放器实例可能被视图更新销毁,影响播放稳定性。

解决方案

1. 补充视频选中后的URL转换逻辑

添加onChange监听选中项变化,将视频数据写入临时文件获取可播放的URL,并初始化AVPlayer。

2. 给VideoPlayer添加明确布局约束

通过frame或aspectRatio修饰符指定视频预览的尺寸,确保视图被正确渲染。

3. 持有AVPlayer实例

用@State变量持有AVPlayer,避免视图更新时播放器被频繁销毁重建。

修改后的完整代码

import SwiftUI
import PhotosUI
import AVKit

struct ContentView: View {
    @State private var text: String = ""
    @State private var selectedPhoto: PhotosPickerItem?
    @State private var image: Image?
    @State private var videoURL: URL?
    @State private var player: AVPlayer?

    var body: some View {
        NavigationStack {
            ZStack{
                LinearGradient(gradient: Gradient(colors: [Color.white, Color.gray]), startPoint: .top, endPoint: .bottom)
                    .ignoresSafeArea()
                VStack {
                    TextField("Type Something", text: $text, axis: .vertical)
                        .padding()
                        .background(Color.white.opacity(0.8))
                        .cornerRadius(8)
                    Spacer()
                    if let videoURL = videoURL, let player = player {
                        VideoPlayer(player: player)
                            .frame(height: 300)
                            .cornerRadius(8)
                            .shadow(radius: 4)
                    }
                }
                .padding()
                .font(.footnote)
            }
            .toolbar {
                PhotosPicker(
                    selection: $selectedPhoto,
                    matching: .videos
                ) {
                    Image(systemName: "pencil")
                }
            }
            .onChange(of: selectedPhoto) { _, newValue in
                guard let newValue = newValue else { return }
                Task {
                    if let data = try? await newValue.loadTransferable(type: Data.self),
                       let tempURL = FileManager.default.temporaryDirectory.appendingPathComponent("temp_video.mp4") {
                        try? data.write(to: tempURL)
                        videoURL = tempURL
                        player = AVPlayer(url: tempURL)
                    }
                }
            }
        }
    }
}

关键说明

  • loadTransferable用于从PhotosPickerItem获取视频数据,写入临时目录生成可被AVPlayer识别的URL。
  • frame(height: 300)给视频预览指定高度,你也可以用.aspectRatio(16/9, contentMode: .fit)来维持视频原始比例。
  • 持有AVPlayer实例可以避免视图重绘时播放器被销毁,保证播放的连续性。

内容的提问来源于stack exchange,提问作者user21597059

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 03:11:26