RxSwift UIAlertController を observable で表示


RxSwift UIAlertController を observable で表示

やり方の例です。

UIAlertActionに相当するオブジェクトを定義

UIAlertActionのクロージャ部分は、onNext処理を入れたいので、事前に代わりになるクラスか構造体を定義しておく。

struct AlertAction {
    var title: String
    var style: UIAlertActionStyle

    static func action(title: String, style: UIAlertActionStyle = .default) -> AlertAction {
        return AlertAction(title: title, style: style)
    }
}

表示部分

上で定義した構造体をUIAlertActionとしてUIAlertControllerにセットする。この時にクロージャ内の処理を定義すること。Observable生成の時でないとこの処理が作れないから事前に仮の構造体を利用しただけ。構造体を用いずにこの中でObserverとなるUIAlertActionを生成してもOK。
「return Disposables」内でUIAlertActionを閉じるのを忘れないように。

func showAlert(title: String?, message: String?, style: UIAlertControllerStyle, actions: [AlertAction]) -> Observable<Int>
{
    return Observable.create { observer in
        let alertController = UIAlertController(title: title, message: message, preferredStyle: style)

        actions.enumerated().forEach { index, action in
            let action = UIAlertAction(title: action.title, style: action.style) { _ in
                observer.onNext(index)
                observer.onCompleted()
            }
            alertController.addAction(action)
        }

        self.present(alertController, animated: true, completion: nil)

        return Disposables.create { alertController.dismiss(animated: true, completion: nil) }
    }
}

利用例

self.showAlert(title: "タイトル", message: "メッセージ", style: .alert,
 actions: [AlertAction.action(title: "no", style: .destructive), AlertAction.action(title: "yes")]
).subscribe(onNext: { selectedIndex in
    print(selectedIndex)
}).disposed(by: self.disposeBag)

サンプル

関連リンク

UIAlertControllerをいかに簡易にまとめる事が大事かと考え作成してみました。
UIAlertController をRxSwiftを使って拡張してみました。

RxAlert