如何在ios中使用swiftui隐藏音量指示器

问题描述 投票:0回答:2

我正在使用苹果媒体播放器编写一个音乐播放器应用程序,并且有一个按钮可以更改音量并隐藏系统默认音量覆盖。 然而,我找到的所有方法都是基于 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 的新手,有人可以帮助我吗?

ios swift xcode swiftui uikit
2个回答
0
投票

我有同样的问题,你的例子帮助我弄清楚了,你显然已经快到了。

这是 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 上发现了非工作示例。


0
投票

您可以复制下面的代码以使用自定义修饰符来隐藏音量 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 进行测试

© www.soinside.com 2019 - 2024. All rights reserved.