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

SwiftUI 4(iOS 16 Beta)如何显示从相册选择的视频?

解决方案

你的问题核心在于当前代码仅处理了图片转UIImage的渲染逻辑,视频的二进制数据无法通过UIImage解析,需要区分媒体类型并使用视频播放组件来处理。以下是修改后的完整实现及说明:

1. 新增必要框架导入

添加AVKit框架,用于视频播放功能:

import AVKit

2. 定义媒体类型枚举

创建枚举区分图片和视频,统一管理选中的媒体内容:

enum Media {
    case image(UIImage)
    case video(URL)
}

3. 调整状态变量

将原data: Data?替换为存储媒体类型的状态变量:

@State var selectedMedia: Media?

4. 修改媒体加载逻辑

优先尝试加载图片类型,失败则加载视频的临时URL(系统会自动生成视频的临时文件路径):

5. 根据媒体类型渲染视图

在界面中根据selectedMedia的类型,分别显示图片或视频播放器。


修改后的完整代码:

import SwiftUI
import PhotosUI
import AVKit

enum Media {
    case image(UIImage)
    case video(URL)
}

struct ContentView: View {
    @State var selectedItems: [PhotosPickerItem] = []
    @State var selectedMedia: Media?
    
    var body: some View {
        VStack {
            // 根据选中的媒体类型渲染对应视图
            if let media = selectedMedia {
                switch media {
                case .image(let uiImage):
                    Image(uiImage: uiImage)
                        .resizable()
                        .scaledToFit()
                case .video(let videoURL):
                    VideoPlayer(player: AVPlayer(url: videoURL))
                        .scaledToFit()
                        .cornerRadius(8)
                }
            }
            
            PhotosPicker(selection: $selectedItems,
                         maxSelectionCount: 1,
                         matching: .any(of: [.images,.videos])) {
                Text("选择媒体")
            }
            .onChange(of: selectedItems) { newItems in
                guard let item = newItems.first else {
                    selectedMedia = nil
                    return
                }
                
                // 先尝试加载图片
                item.loadTransferable(type: UIImage.self) { result in
                    switch result {
                    case .success(let image):
                        if let image = image {
                            selectedMedia = .image(image)
                            return
                        }
                        // 图片加载失败,尝试加载视频URL
                        fallthrough
                    case .failure:
                        item.loadTransferable(type: URL.self) { videoResult in
                            switch videoResult {
                            case .success(let videoURL):
                                if let videoURL = videoURL {
                                    selectedMedia = .video(videoURL)
                                }
                            case .failure(let error):
                                print("加载媒体失败: \(error.localizedDescription)")
                            }
                        }
                    }
                }
            }
        }
        .padding()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

关键说明:

  • VideoPlayer是SwiftUI 4新增的原生视图,直接传入AVPlayer实例即可实现视频播放,无需额外复杂配置。
  • 视频加载时,PhotosPickerItem会返回系统生成的临时文件URL,可直接用于播放,无需手动处理文件存储。
  • 先尝试加载图片再加载视频的逻辑,确保两种类型的媒体都能被正确识别和渲染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 10:57:35