はじめに
アプリでアラートダイアログを出す際、標準のものではなくカスタムしたダイアログを出したい場面があると思います。
ダイアログのタイトルやメッセージを自由に変えられるような汎用性の高い自前のダイアログを作成してみました。
某アプリのようなダイアログも出せます。
ソースコード
まずはベースのCustomViewを作成します
import UIKit
@IBDesignable
class CustomView: UIView {
var baseView: UIView?
/// コードから生成したときに通る初期化処理
override init(frame: CGRect) {
super.init(frame: frame)
self.commonInit()
self.viewDidLoad()
}
/// InterfaceBulderで配置した場合に通る初期化処理
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.commonInit()
self.viewDidLoad()
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
self.commonInit()
self.viewDidLoad()
}
func viewDidLoad() {}
func commonInit() {
guard let view = UINib(nibName: String(describing: type(of: self)), bundle: Bundle(for: type(of: self))).instantiate(withOwner: self, options: nil).first as? UIView else {
return
}
view.frame = self.bounds
view.autoresizingMask = [.flexibleHeight, .flexibleWidth]
self.addSubview(view)
self.baseView = view
}
}
そしてこいつを継承させたConfirmDialogを作成します。
これが画面に出るダイアログのViewです
import UIKit
final class ConfirmDialog: CustomView {
@IBOutlet private weak var cancelButton: UIButton!
@IBOutlet private weak var okButton: UIButton!
@IBOutlet private weak var title: UILabel!
@IBOutlet private weak var message: UILabel!
@IBOutlet weak var dialogBaseView: UIView!
private var okAction: (() -> Void)?
private var cancelAction: (() -> Void)?
override func viewDidLoad() {
super.viewDidLoad()
dialogBaseView.layer.cornerRadius = 5
okButton.layer.cornerRadius = 5
cancelButton.layer.cornerRadius = 5
}
@IBAction func tappedOkButton(_ sender: UIButton) {
self.okAction?()
self.removeFromSuperview()
}
@IBAction func tappedCancelButton(_ sender: UIButton) {
self.cancelAction?()
self.removeFromSuperview()
}
func set(
title: String,
message: String,
okButtonTitle: String,
cancelButtonTitle: String,
okAction: (() -> Void)?,
cancelAction: (() -> Void)?) {
if title == "" {
self.title.isHidden = true
} else {
self.title.text = title
}
self.message.text = message
self.cancelButton.setTitle(cancelButtonTitle, for: .normal)
self.okButton.setTitle(okButtonTitle, for: .normal)
self.okAction = okAction
self.cancelAction = cancelAction
}
}
Xcode上だとこんな感じ
そして、UIViewControllerにExtensionしておくことですぐに呼び出すことができます。
import UIKit
extension UIViewController {
/// ダイアログを呼び出す
func showConfirmDialog(
title: String,
message: String,
cancelButtonTitle: String,
okButtonTitle: String,
okAction: (() -> Void)? = nil,
cancelAction: (() -> Void)? = nil
) {
let confirmDialog = ConfirmDialog(frame: self.view.frame)
confirmDialog.set(title: title, message: message, okButtonTitle: okButtonTitle, cancelButtonTitle: cancelButtonTitle, okAction: okAction, cancelAction: cancelAction)
self.view.addSubview(confirmDialog)
}
}
実際に呼び出すときの記述↓
import UIKit
final class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func tappedDialogButton(_ sender: Any) {
// ここでダイアログを呼び出し
self.showConfirmDialog(
title: "サンプル", message: "これはサンプルです", cancelButtonTitle: "キャンセル", okButtonTitle: "OK",
okAction: {
print("OK")
},cancelAction: {
print("キャンセルしました")
})
}
}
タイトル、メッセージ、ボタンタイトルも自由に変更できます。
okActionとcancelActionはクロージャになっているのでタップ時の処理もそれぞれ決めることができますね。
まとめ
使い勝手は良いと思うので、デザインなどカスタマイズしたい場合はこのようなダイアログを作成すると楽だと思いました。
ソースはGitHubに上げております↓↓
https://github.com/taro-ken/CustomViewSample