LoginSignup
11
13

More than 5 years have passed since last update.

[iOS] Xibを使って自前のダイアログを作る

Posted at

きっかけ

Androidとおなじにしてよ。っていわれたのが最初のきっかけです。
IDやパスワードを入力したり、カスタマイズがしやすいようにXibでAlertViewが簡単に作れるといいなと思いました。

今までこんな書き方をよく使ってましたが
self.presentViewController(vc, animated: true, completion: nil)

Viewを上に重ねるだけでなく、Alertっぽくしたい!!っていうのが一番の希望。

でも

でも、実際Alertなわけではなく、ViewControllerをAlertっぽくみせているだけです

プロジェクトを作る

シングルビューアプリケーションでプロジェクトを作ります

ss00.png

プロジェクト名を入力します

ss02.png

Alertに使うViewControllerを作ります

メニューからFile-New-FileでCocoa Touch Classを選択します。

ss01.png

ViewControllerの名前をつけます

*Also create XIB fileにチェックをつけます
ss03.png

出来上がったMyAlertViewController.swiftを修正します

*画面遷移のアニメーションをカスタマイズするのでUIViewControllerTransitioningDelegateを追加します
ss04.png

外観のカスタマイズ

MyAlertViewController.Xibにボタンをつけたり、タイトルをつけてMyAlertViewController.swiftとOutletで結んでください。
ss06.png

MyAlertViewController.swiftを編集

3つのinit

1.xibを初期化するinit。背景を透明にしたり、アニメーションをカスタマイズする設定をします

MyAlertViewController.swift
override init(nibName nibNameOrNil:String?, bundle ninBundleOrNil:Bundle? ){
        super.init(nibName:nibNameOrNil,bundle:ninBundleOrNil)
        self.transitioningDelegate = self
        self.providesPresentationContextTransitionStyle = true
        self.definesPresentationContext = true
        self.modalPresentationStyle = .custom

    }

2.実際に使用する初期化処理です

MyAlertViewController.swift
    convenience init(title:String,desc:String){
        self.init(nibName:"MyAlertViewController",bundle:nil)
        titleText = title
        messageText = desc
    }

3.普通のinitは使わないのでエラーにします

MyAlertViewController.swift
    required init?(coder aDecider: NSCoder){
        fatalError("init error")
    }

UIViewControllerTransitioningDelegate

デフォルトのアニメーションだと画面下から上に移動するアニメーションなので書き換えます

MyAlertViewController.swift
    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return AlertAnimation(show:true)
    }
    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return AlertAnimation(show:false)
    }

アニメーションの実態を書きます

class MyAlertViewController: UIViewController,UIViewControllerTransitioningDelegate {

の最後の括弧「}」が閉じてから下に付け足すか、もしくは別ファイルにしてください

MyAlertViewController.swift
class AlertAnimation : NSObject, UIViewControllerAnimatedTransitioning {

    let show: Bool

    init(show: Bool) {
        self.show = show
    }
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        if (show) {
            return 0.45
        } else {
            return 0.25
        }
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        if (show) {
            self.presentAnimateTransition(transitionContext: transitionContext)
        } else {
            self.dismissAnimateTransition(transitionContext: transitionContext)
        }
    }

    func presentAnimateTransition(transitionContext: UIViewControllerContextTransitioning) {

        let alertVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) as! MyAlertViewController
        alertVC.view.frame = UIScreen.main.bounds
        let containerView = transitionContext.containerView
        alertVC.alertView.alpha = 0.0
        alertVC.alertView.center = alertVC.view.center
        alertVC.alertView.transform = CGAffineTransform.init(scaleX: 0.5, y: 0.5)
        containerView.addSubview(alertVC.view)

        UIView.animate(withDuration: 0.25,
                       animations: {
                                    alertVC.view.alpha = 1.0
                                    alertVC.alertView.alpha = 1.0
                                    alertVC.alertView.transform = CGAffineTransform.init(scaleX: 1.05, y:1.05)
        },
                                   completion: { finished in
                                    UIView.animate(withDuration:0.2,
                                                    animations: {
                                                    alertVC.alertView.transform = CGAffineTransform.identity
                                    },
                                                    completion: { finished in
                                                            if (finished) {
                                                                    transitionContext.completeTransition(true)
                                                            }
                                    })
        })
    }
    func dismissAnimateTransition(transitionContext: UIViewControllerContextTransitioning) {

        let alertVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from) as! MyAlertViewController

        UIView.animate(withDuration:self.transitionDuration(using: transitionContext),
                                   animations: {
                                    alertVC.view.alpha = 0.0
                                    alertVC.alertView.alpha = 0.0
                                    alertVC.alertView.transform = CGAffineTransform.init(scaleX: 0.9, y: 0.9)
        },
                                   completion: { finished in
                                    transitionContext.completeTransition(true)
        })
    }
}

ソース

GitHubにおきました

11
13
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
11
13