11
13

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.

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

Posted at

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

今までこんな書き方をよく使ってましたが

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?