完成イメージは以下の通り。
参考: http://stackoverflow.com/questions/32790207/uialertcontroller-add-custom-views-to-actionsheet
実現方法
UIAlertController
はUIViewController
を継承しているので、view
プロパティを持っています。
そのため、view
に任意のビューを追加することができます。
今回は以下のようなUIAlertController
を継承したクラスを作りました。
import Foundation
import UIKit
class MyAlertController: UIAlertController {
public var customView: UIView?
public var customViewMarginBottom: CGFloat = 16
override func viewDidLoad() {
super.viewDidLoad()
guard let customView = self.customView else {
return
}
customView.frame.origin.y = -customView.frame.height - self.customViewMarginBottom
self.view.addSubview(customView)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
guard let customView = self.customView else {
return
}
UIView.animate(withDuration: 0.1) {
customView.alpha = 0
}
}
}
ポイント1: customView
のframe.origin.y
をマイナスにする
UIAlertController
のview
のフレームは、タイトルが表示されているブロックの左上が(0, 0)となっています。今回はもっと上にビューを表示したいので、追加するビューのy座標をマイナスにしたうえで追加します。
view
のclipsToBounds
はfalse
のままにしておいてください。
ポイント2: viewWillDisappear
にcustomView
のアニメーションを追加する
view
にビューを追加するだけで、表示されるときはいい感じにアニメーションしてくれます。
しかし、y座標をマイナスにしているため、消えるときはcustomView
だけが取り残されたようなアニメーションになってしまいます。
そのため、customView
を透明にするアニメーションをviewWillDisappear
に書いてやります。
使う
追加したいビューを用意し、MyAlertController
のcustomView
に突っ込んでやるだけです。
ビューの幅をActionSheetと同じくらいにしたいときは、試した限りではx
を0
、width
をself.view.frame.width-20
にしたらいい感じになりました。
...
@IBAction func showSheet(_ sender: Any) {
let view = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width-20, height: 100))
view.backgroundColor = .green
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 30))
label.backgroundColor = .orange
label.text = "custom view"
label.textColor = .white
label.textAlignment = .center
view.addSubview(label)
let alert = MyAlertController(
title : "ほげ",
message : "ふが",
preferredStyle : .actionSheet
)
alert.addAction(UIAlertAction(
title : "へい",
style : .default,
handler : nil
))
alert.addAction(UIAlertAction(
title : "へい",
style : .destructive,
handler : nil
))
alert.addAction(UIAlertAction(
title : "へい",
style : .cancel,
handler : nil
))
alert.customView = view
self.present(alert, animated: true, completion: nil)
}
...