在 SwiftUI 应用程序中放置音频播放代码的位置[关闭]
Posted
技术标签:
【中文标题】在 SwiftUI 应用程序中放置音频播放代码的位置[关闭]【英文标题】:Where to place code for audio playback in a SwiftUI app [closed] 【发布时间】:2019-07-17 05:11:51 【问题描述】:在基于 SwiftUI 的应用程序中放置音频播放代码的最佳位置是哪里,即没有 UIViewController 类?我要播放的声音是由一个视图发起的,所以我想把它放到对应的视图模型类中。但由于模型类是关于数据的,我认为应该有更好的选择。最好的架构是什么?
【问题讨论】:
【参考方案1】:正确,视图不应该处理数据。 SwiftUI 强制执行此逻辑。
您可以创建一个播放器类来负责播放音频。并将其添加为EnvironmentObject
,这样您就可以使用View
中的按钮来控制它。然后,您可以做一些甜蜜的事情,例如绑定您的播放按钮以根据播放器是否正在播放不同的图像:)
更新
Xcode 11 beta 4 的代码已更新(willChange
而不是 didChange
)
struct PlayerView : View
@EnvironmentObject private var player: Player
var body: some View
Button(action:
self.player.pauseOrPlay()
)
Image(systemName: player.isPlaying ? "pause.circle.fill" : "play.circle.fill").font(.title).frame(minWidth: 44, minHeight: 44)
class Player: BindableObject
let willChange = PassthroughSubject<Player, Never>()
var isPlaying: Bool = false
willSet
willChange.send(self)
func pauseOrPlay()
// Code that toggles the audio on and off
【讨论】:
我得到了这个错误 Swift5.0 -- 类中的 BindableObject 给出了这个错误 Use of undeclared type 'BindableObject' and @EnvironmentObject private var player: Player 给出错误 Property type 'Player' does not match that of the 'wrappedValue' property of the wrapper type 'EnvironmentObject' @uplearnedu.comBindableObject
已更改为 ObservableObject
参见:developer.apple.com/documentation/combine/observableobject【参考方案2】:
尽管 Davide 的解决方案有效,但我最终还是使用了单例模式来全局访问我的声音播放器对象,并且实际上将声音的触发从视图移回了模型类。
看起来像这样:
class Player
static let shared = AudioPlayer()
func pauseOrPlay()
// Code that toggles the audio on and off
我现在可以从任何地方调用它:
Player.shared.pauseOrPlay()
【讨论】:
一个环境对象是一个具有全局访问权限的单例,所以不清楚你做了什么不同的事情。你能提供一些实际的代码吗? 我只是为 Player 使用了一个“普通”类(即不符合 BindableObject)并添加了该类的静态实例常量。我实际上不再需要可绑定的东西,因为我将触发代码移回模型并且不需要我的 UI 来对播放器状态做出反应。以上是关于在 SwiftUI 应用程序中放置音频播放代码的位置[关闭]的主要内容,如果未能解决你的问题,请参考以下文章