我正在使用苹果媒体播放器编写一个音乐播放器应用程序,并且有一个按钮可以更改音量并隐藏系统默认音量覆盖。 然而,我找到的所有方法都是基于 UIKit 的。 喜欢
let volumeView = MPVolumeView(frame: .zero)
volumeView.clipsToBounds = true
volumeView.alpha = 0.00001
volumeView.showsVolumeSlider = false
view.addSubview(volumeView)
我尝试过
import Foundation
import SwiftUI
import MediaPlayer
struct VolumeView:UIViewRepresentable{
let volumeView:MPVolumeView
func makeUIView(context: Context) -> MPVolumeView {
volumeView.clipsToBounds = true
volumeView.alpha = 0.00001
volumeView.showsVolumeSlider = false
return volumeView
}
func updateUIView(_ uiView: MPVolumeView, context: Context) {
}
typealias UIViewType = MPVolumeView
}
它接收我在视图模型中创建的 MPVolumeView 并将其放置在 swiftui 视图中。指示器消失但无法改变音量。 然后我尝试在 UIViewRepresentable 中创建 MPVolumeView 的新实例,但它也不起作用。 我是 swiftui 的新手,有人可以帮助我吗?
我有同样的问题,你的例子帮助我弄清楚了,你显然已经快到了。
这是 SwiftUI 中完整的自定义音量滑块
struct VolumeSliderView: View {
var primaryColor: Color
@StateObject var volumeViewModel = VolumeViewModel()
var body: some View {
ZStack {
VolumeView()
.frame(width: 0, height: 0)
Slider(value: $volumeViewModel.volume, in: 0...1) {
Text("")
} minimumValueLabel: {
Image(systemName: "speaker.fill")
.font(.callout)
.foregroundColor(primaryColor.opacity(0.6))
} maximumValueLabel: {
Image(systemName: "speaker.wave.3.fill")
.font(.callout)
.foregroundColor(primaryColor.opacity(0.6))
} onEditingChanged: { isEditing in
volumeViewModel.setVolume()
}
.tint(primaryColor.opacity(0.6))
}
}
}
import Foundation
import MediaPlayer
struct VolumeView: UIViewRepresentable{
func makeUIView(context: Context) -> MPVolumeView {
let volumeView = MPVolumeView(frame: CGRect.zero)
volumeView.alpha = 0.001
return volumeView
}
func updateUIView(_ uiView: MPVolumeView, context: Context) {
}
}
似乎 MPVolumeView 的实例需要随时出现在屏幕上,即使它不可见。看起来有点老套但有效。如果我只在
setVolume()
函数中隐藏视图,甚至在那里调用 volumeView.showsVolumeSlider = false
,那不会有什么区别。
class VolumeViewModel: ObservableObject {
@Published var volume: Float = 0.5
init() {
setInitialVolume()
}
private func setInitialVolume() {
volume = AVAudioSession().outputVolume
}
func setVolume() {
let volumeView = MPVolumeView()
let slider = volumeView.subviews.first(where: { $0 is UISlider }) as? UISlider
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.03) {
slider?.setValue(self.volume, animated: false)
}
}
}
希望它对某人有帮助,因为我刚刚在 SO 上发现了非工作示例。
您可以复制下面的代码以使用自定义修饰符来隐藏音量 HUD。
struct VolumeViewModifier: ViewModifier {
func body(content: Content) -> some View {
ZStack {
VolumeView()
.frame(width: 0, height: 0)
content
}
}
struct VolumeView: UIViewRepresentable{
func makeUIView(context: Context) -> MPVolumeView {
let volumeView = MPVolumeView(frame: CGRect.zero)
volumeView.alpha = 0.001
return volumeView
}
func updateUIView(_ uiView: MPVolumeView, context: Context) { }
}
}
extension View {
func hideVolumeHUD() -> some View {
modifier(VolumeViewModifier())
}
}
用途:
Text("Hiding the volume HUD. This can be any view")
.hideVolumeHUD()
只要附加了此修改器的任何可见视图,体积 HUD 都不会出现。已针对 iOS 进行测试