SwiftUI - 更改视图时音频继续播放
SwiftUI - Audio keeps playing when changing views
自从我更新 Xcode 后,我遇到了一个问题...除非用户在音频视图中点击暂停。当用户更改视图时,我的音频播放器继续播放,但我希望音频在用户退出播放器视图 (ItemDetail) 时停止(例如,当用户转到内容视图时)
之前我在内容视图的开头使用了下面的内容,这曾经奏效,但现在没有了:
init() { sounds.pauseSounds() }
我也试过这个(也没用):
}// end of navigation view .onAppear{sounds.pauseSounds()}
这是我的声音class:
class Sounds:ObservableObject {
var player:AVAudioPlayer?
// let shared = Sounds()
func playSounds(soundfile: String) {
if let path = Bundle.main.path(forResource: soundfile, ofType: nil){
do{
player = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
player?.prepareToPlay()
player?.play()
}catch {
print("Error can't find sound file or something's not working with the sounds model")
}
}
}
// This method used to work at pausing the sound (pre-update)
func pauseSounds() {
player?.pause()
}
// over rides the sound defaulting to bluetooth speaker only and sends it to phone speaker if bluetooth is not available (headset/speaker) however if it is available it'll play through that.
func overRideAudio() {
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(AVAudioSession.Category.playback, mode: .spokenAudio, options: .defaultToSpeaker)
try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
} catch {
print("error.")
}
}
}
这是播放器视图:
struct ItemDetail: View {
@State var isPlaying = false
var item : SessionsItem
@ObservedObject var soundsPlayer = Sounds()
var body: some View {
HStack {
Button(action: {
if self.isPlaying{
// Sounds.player?.pause()
self.isPlaying = false
soundsPlayer.pauseSounds()
}
else{
self.isPlaying = true
soundsPlayer.playSounds(soundfile: "\(self.item.name).mp3")
soundsPlayer.overRideAudio()
}
onAppear
不是像这样工作的可靠方法 SwiftUI
做了很多预加载(List
很明显)。这取决于设备及其功能。有时屏幕在预加载时“出现”,不一定在用户查看时出现。
下面的List
例子你可以在模拟器中看到。
在 iPhone 8 上,当我最初加载它时,我在控制台中得到 12 onAppear
print
语句,在 iPhone 12 Pro Max 上,我得到 17 [=16] =] 语句。
如果单元格 more/less 复杂,您会得到相应的 more/less 语句。你应该找到另一种方法来做到这一点。
import SwiftUI
struct ListCellAppear: View {
var idx: Int
var body: some View {
HStack{
Text(idx.description)
Image(systemName: "checkmark")
}.onAppear(){
print(idx.description)
}
}
}
struct ListAppear: View {
var body: some View {
List(0..<1000){ idx in
ListCellAppear(idx: idx).frame(height: 300)
}
}
}
struct ListAppear_Previews: PreviewProvider {
static var previews: some View {
ListAppear()
}
}
您正在创建另一个声音实例,因此您无权访问打开的音频实例。您可以将 Sounds class 作为单个实例或将 Sounds 实例传递给细节。不要创建一个新的。
自从我更新 Xcode 后,我遇到了一个问题...除非用户在音频视图中点击暂停。当用户更改视图时,我的音频播放器继续播放,但我希望音频在用户退出播放器视图 (ItemDetail) 时停止(例如,当用户转到内容视图时)
之前我在内容视图的开头使用了下面的内容,这曾经奏效,但现在没有了:
init() { sounds.pauseSounds() }
我也试过这个(也没用):
}// end of navigation view .onAppear{sounds.pauseSounds()}
这是我的声音class:
class Sounds:ObservableObject {
var player:AVAudioPlayer?
// let shared = Sounds()
func playSounds(soundfile: String) {
if let path = Bundle.main.path(forResource: soundfile, ofType: nil){
do{
player = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
player?.prepareToPlay()
player?.play()
}catch {
print("Error can't find sound file or something's not working with the sounds model")
}
}
}
// This method used to work at pausing the sound (pre-update)
func pauseSounds() {
player?.pause()
}
// over rides the sound defaulting to bluetooth speaker only and sends it to phone speaker if bluetooth is not available (headset/speaker) however if it is available it'll play through that.
func overRideAudio() {
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(AVAudioSession.Category.playback, mode: .spokenAudio, options: .defaultToSpeaker)
try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
} catch {
print("error.")
}
}
}
这是播放器视图:
struct ItemDetail: View {
@State var isPlaying = false
var item : SessionsItem
@ObservedObject var soundsPlayer = Sounds()
var body: some View {
HStack {
Button(action: {
if self.isPlaying{
// Sounds.player?.pause()
self.isPlaying = false
soundsPlayer.pauseSounds()
}
else{
self.isPlaying = true
soundsPlayer.playSounds(soundfile: "\(self.item.name).mp3")
soundsPlayer.overRideAudio()
}
onAppear
不是像这样工作的可靠方法 SwiftUI
做了很多预加载(List
很明显)。这取决于设备及其功能。有时屏幕在预加载时“出现”,不一定在用户查看时出现。
下面的List
例子你可以在模拟器中看到。
在 iPhone 8 上,当我最初加载它时,我在控制台中得到 12 onAppear
print
语句,在 iPhone 12 Pro Max 上,我得到 17 [=16] =] 语句。
如果单元格 more/less 复杂,您会得到相应的 more/less 语句。你应该找到另一种方法来做到这一点。
import SwiftUI
struct ListCellAppear: View {
var idx: Int
var body: some View {
HStack{
Text(idx.description)
Image(systemName: "checkmark")
}.onAppear(){
print(idx.description)
}
}
}
struct ListAppear: View {
var body: some View {
List(0..<1000){ idx in
ListCellAppear(idx: idx).frame(height: 300)
}
}
}
struct ListAppear_Previews: PreviewProvider {
static var previews: some View {
ListAppear()
}
}
您正在创建另一个声音实例,因此您无权访问打开的音频实例。您可以将 Sounds class 作为单个实例或将 Sounds 实例传递给细节。不要创建一个新的。