Как отобразить меню AirPlay SwiftUI - PullRequest
0 голосов
/ 05 февраля 2020

Благодаря аудиосистеме трансляцииName emoji я сделал хорошую иконку

Button(action: {
        showAirplay()
}, label: {
    Image(systemName: "airplayaudio")
        .imageScale(.large)
})

func showAirplay() {
       ???
}

Но я не знаю, как отобразить знаменитое меню:

1 Ответ

0 голосов
/ 06 февраля 2020

Наконец-то мне удалось решить это самому: D Как сказано в комментарии, я должен «встроить его» в UIKit и использовать его в SwiftUI

Сначала:

struct AirPlayButton: UIViewControllerRepresentable {
    func makeUIViewController(context: UIViewControllerRepresentableContext<AirPlayButton>) -> UIViewController {
        return AirPLayViewController()
    }

    func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<AirPlayButton>) {

    }
}

Затем класс c ViewController, откуда мы знаем от веков как показать это знаменитое всплывающее меню AirPlay:

class AirPLayViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let isDarkMode = self.traitCollection.userInterfaceStyle == .dark

        let button = UIButton()
        let boldConfig = UIImage.SymbolConfiguration(scale: .large)
        let boldSearch = UIImage(systemName: "airplayaudio", withConfiguration: boldConfig)

        button.setImage(boldSearch, for: .normal)
        button.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
        button.backgroundColor = .red
        button.tintColor = isDarkMode ? .white : .black

        button.addTarget(self, action: #selector(self.showAirPlayMenu(_:)), for: .touchUpInside)
        self.view.addSubview(button)
    }

    @objc func showAirPlayMenu(_ sender: UIButton){ // copied from https://stackoverflow.com/a/44909445/7974174
        let rect = CGRect(x: 0, y: 0, width: 0, height: 0)
        let airplayVolume = MPVolumeView(frame: rect)
        airplayVolume.showsVolumeSlider = false
        self.view.addSubview(airplayVolume)
        for view: UIView in airplayVolume.subviews {
            if let button = view as? UIButton {
                button.sendActions(for: .touchUpInside)
                break
            }
        }
        airplayVolume.removeFromSuperview()
    }
}

Наконец, в SwiftUI просто вызовите:

struct ContentView: View {
    var body: some View {
        VStack {
            Text("Hello World")
            AirPlayButton().frame(width: 40, height: 40) // (important to be consistent with this frame, like that it is nicely centered... see button.frame in AirPlayViewController)

        }
    }
}
...