如何让 Picker 使用 ForEach 循环返回 VideoFormat var?
Posted
技术标签:
【中文标题】如何让 Picker 使用 ForEach 循环返回 VideoFormat var?【英文标题】:How can I get Picker to return a VideoFormat var using a ForEach loop? 【发布时间】:2021-02-21 15:48:26 【问题描述】:我正在尝试使用 Picker 通过 ForEach 循环从 Twilio 的视频 API 中选择一个 VideoFormat。循环正在运行——它列出了所有格式正确的格式字符串。
这是我的看法,SettingsView
:
import SwiftUI
struct SettingsView: View
@EnvironmentObject var twiliostate: TwilioState
var body: some View
Form
Section(header: Text("Stream"))
HStack
Text("Device")
Spacer()
Text("\(twilioState.captureDevice?.localizedName ?? "N/A")")
这就是我遇到麻烦的地方。我似乎无法让Picker
为我的selection
、$twilioState.videoFormat
赋值。我怀疑这与id
和VideoFormat
不符合Hashable
有关吗?我正在考虑将selection
更改为Int
并使用ForEach
的范围,例如0..<twilioState.videoFormats.count
。
Picker("Select a Format", selection: $twilioState.videoFormat)
if let videoFormats = twilioState.videoFormats
ForEach(videoFormats, id: \.self)
Text("\(twilioState.getVideoFormatString(videoFormat: $0))")
.tag($0)
.disabled(twilioState.videoFormats == nil)
其余的是twilioState.videoFormat
的列表,因为我试图弄清楚如何成功实施Picker
。
HStack
Text("Format")
Spacer()
if let videoFormat = twilioState.videoFormat
Text("\(twilioState.getVideoFormatString(videoFormat: videoFormat))")
else
Text("N/A")
.navigationBarTitle("Settings")
这是我的状态模型,TwilioState
:
import Foundation
import TwilioVideo
import Combine
class TwilioState: ObservableObject
let twilioService = TwilioService()
private var cancellables = Set<AnyCancellable>()
var camera: CameraSource?
@Published var videoFormat: VideoFormat?
@Published var videoFormats: [VideoFormat]?
@Published var captureDevice: AVCaptureDevice?
@Published var twilioError: TwilioError?
init()
twilioService.setCaptureDevice(captureDevice: self.captureDevice)
.sink completion in
switch completion
case let .failure(twilioError):
return self.twilioError = twilioError
case .finished:
return print("Capture device set")
receiveValue: captureDevice in
self.captureDevice = captureDevice
.store(in: &cancellables)
twilioService.getVideoFormats(captureDevice: self.captureDevice!)
.sink completion in
switch completion
case let .failure(twilioError):
return self.twilioError = twilioError
case .finished: return print("Capture device formats set")
receiveValue: videoFormats in
self.videoFormats = videoFormats
.store(in: &cancellables)
func getVideoFormatString(videoFormat: VideoFormat) -> String
return "\(videoFormat.dimensions.width) x \(videoFormat.dimensions.height) @ \(videoFormat.frameRate)"
deinit
// We are done with camera
if let camera = self.camera
camera.stopCapture()
self.camera = nil
如果有帮助,这是服务功能,getVideoFormats()
,它在我的模型TwilioState
中向@Published videoFormats
提供值:
func getVideoFormats(captureDevice: AVCaptureDevice) -> AnyPublisher<[VideoFormat], TwilioError>
return Just(captureDevice)
.map captureDevice -> [VideoFormat] in
return CameraSource.supportedFormats(captureDevice: captureDevice)
.compactMap $0 as? VideoFormat
.setFailureType(to: TwilioError.self)
.eraseToAnyPublisher()
【问题讨论】:
【参考方案1】:我通过使用标签修饰符将选择类型转换为可选类型解决了这个问题:
Picker("Select a Format", selection: $twilioState.videoFormat)
if let videoFormats = twilioState.videoFormats
ForEach(videoFormats, id: \.self) videoFormat in
Text("\(twilioState.getVideoFormatString(videoFormat: videoFormat))")
.tag(videoFormat as VideoFormat?)
查看此帖子了解更多信息:Picker for optional data type in SwiftUI?
【讨论】:
以上是关于如何让 Picker 使用 ForEach 循环返回 VideoFormat var?的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI:如何根据 Picker 的值更新 ForEach 循环的范围
SwiftUI Picker 填充问题 - 选择器中的 ForEach 循环不填充
如何在 Swiftui 中与其他组件一起在 ScrollView 或 VStack 中完全显示 Picker?