14
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

UIAlertControllerのActionSheetの上にビューを追加する

Posted at

完成イメージは以下の通り。

ope.gif

参考: http://stackoverflow.com/questions/32790207/uialertcontroller-add-custom-views-to-actionsheet

実現方法

UIAlertControllerUIViewControllerを継承しているので、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: customViewframe.origin.yをマイナスにする

UIAlertControllerviewのフレームは、タイトルが表示されているブロックの左上が(0, 0)となっています。今回はもっと上にビューを表示したいので、追加するビューのy座標をマイナスにしたうえで追加します。
viewclipsToBoundsfalseのままにしておいてください。

ポイント2: viewWillDisappearcustomViewのアニメーションを追加する

viewにビューを追加するだけで、表示されるときはいい感じにアニメーションしてくれます。
しかし、y座標をマイナスにしているため、消えるときはcustomViewだけが取り残されたようなアニメーションになってしまいます。
そのため、customViewを透明にするアニメーションをviewWillDisappearに書いてやります。

使う

追加したいビューを用意し、MyAlertControllercustomViewに突っ込んでやるだけです。
ビューの幅をActionSheetと同じくらいにしたいときは、試した限りではx0widthself.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)
    }
...
14
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?