🤖
背景透過なViewControllerをクロスディゾルブでモーダル表示
iOS 7とiOS 8でやり方が違うので実は結構面倒だったりする。
- iOS 7は遷移元のViewControllerに対してごにょごにょ
- iOS 8は遷移先のViewControllerに対してごにょごにょ
iOS 7の場合
モーダルを出す時
modalPresentationStyle = .CurrentContext
modalTransitionStyle = .CrossDissolve
navigationController?.modalPresentationStyle = .CurrentContext
navigationController?.modalTransitionStyle = .CrossDissolve
presentViewController(controller, animated: animated, completion: {
[weak self] () -> Void in
// 遷移が終わったら元の状態に戻す。モーダルから戻ってきた後に別のモーダルを出そうとしてクロスディゾルブのままだったりする
self?.modalPresentationStyle = .FullScreen
self?.modalTransitionStyle = .CoverVertical
self?.navigationController?.modalPresentationStyle = .FullScreen
self?.navigationController?.modalTransitionStyle = .CoverVertical
})
モーダルを閉じる時
modalPresentationStyle = .CurrentContext
modalTransitionStyle = .CrossDissolve
navigationController?.modalPresentationStyle = .CurrentContext
navigationController?.modalTransitionStyle = .CrossDissolve
dismissViewControllerAnimated(true, completion: nil)
iOS 8の場合
モーダルを出す時
controller.modalPresentationStyle = .OverCurrentContext
controller.modalTransitionStyle = .CrossDissolve
presentViewController(controller, animated: animated, completion: nil)
モーダルを閉じる時
presentingViewController?.modalPresentationStyle = .OverCurrentContext
presentingViewController?.modalTransitionStyle = .CrossDissolve
// completionの中で、self?.presentingViewController とやってもnilなので
let p = presentingViewController
dismissViewControllerAnimated(true, completion: {
[weak self] () -> Void in
p?.modalPresentationStyle = .FullScreen
p?.modalTransitionStyle = .CoverVertical
})
まとめると
モーダルを出す時
if iOS8以上 {
controller.modalPresentationStyle = .OverCurrentContext
controller.modalTransitionStyle = .CrossDissolve
} else {
modalPresentationStyle = .CurrentContext
modalTransitionStyle = .CrossDissolve
navigationController?.modalPresentationStyle = .CurrentContext
navigationController?.modalTransitionStyle = .CrossDissolve
}
presentViewController(controller, animated: animated, completion: {
[weak self] () -> Void in
if iOS8以上 { return }
self?.modalPresentationStyle = .FullScreen
self?.modalTransitionStyle = .CoverVertical
self?.navigationController?.modalPresentationStyle = .FullScreen
self?.navigationController?.modalTransitionStyle = .CoverVertical
})
モーダルを閉じる時
if iOS8以上 {
presentingViewController?.modalPresentationStyle = .OverCurrentContext
presentingViewController?.modalTransitionStyle = .CrossDissolve
} else {
modalPresentationStyle = .CurrentContext
modalTransitionStyle = .CrossDissolve
navigationController?.modalPresentationStyle = .CurrentContext
navigationController?.modalTransitionStyle = .CrossDissolve
}
let p = presentingViewController
dismissViewControllerAnimated(true, completion: {
[weak self] () -> Void in
if iOS8以上 {
p?.modalPresentationStyle = .FullScreen
p?.modalTransitionStyle = .CoverVertical
}
})
やってられるか!!
というわけで、以下のようなextension
を用意する。
UIViewController+Extensions.swift
extension UIViewController {
enum Transition {
case Default, CrossDissolve
}
func tak_presentViewController(controller: UIViewController, animated: Bool, transition: Transition) {
tak_presentViewController(controller, animated: animated, transition: transition, completion: nil)
}
func tak_presentViewController(controller: UIViewController, animated: Bool, transition: Transition, completion: (Void -> Void)?) {
if iOS8以上 {
controller.tak_setupTransition(transition)
} else {
tak_setupTransitionForIos7(transition)
}
presentViewController(controller, animated: animated, completion: {
[weak self] () -> Void in
if iOS8以上 { return }
self?.tak_setupTransitionForIos7(.Default)
completion?()
})
}
func tak_dismissViewControllerAnimated(animated: Bool, transition: Transition) {
tak_dismissViewControllerAnimated(animated, transition: transition, completion: nil)
}
func tak_dismissViewControllerAnimated(animated: Bool, transition: Transition, completion: (Void -> Void)?) {
if iOS8以上 {
presentingViewController?.tak_setupTransition(transition)
} else {
tak_setupTransitionForIos7(transition)
}
// completionの中で、self?.presentingViewController とやってもnilなので
let p = presentingViewController
dismissViewControllerAnimated(true, completion: {
[weak self] () -> Void in
if iOS8以上 {
p?.tak_setupTransition(.Default)
}
completion?()
})
}
// iOS7用
private func tak_setupTransitionForIos7(transition: Transition) {
switch transition {
case .Default:
modalPresentationStyle = .FullScreen
modalTransitionStyle = .CoverVertical
case .CrossDissolve:
modalPresentationStyle = .CurrentContext
modalTransitionStyle = .CrossDissolve
}
navigationController?.tak_setupTransitionForIos7(transition)
}
private func tak_setupTransition(transition: Transition) {
switch transition {
case .Default:
modalPresentationStyle = .FullScreen
modalTransitionStyle = .CoverVertical
case .CrossDissolve:
modalPresentationStyle = .OverCurrentContext
modalTransitionStyle = .CrossDissolve
}
}
}
モーダルを出す時
tak_presentViewController(c, animated: true, transition: .CrossDissolve)
モーダルを閉じる時
tak_dismissViewControllerAnimated(animated: true, transition: .CrossDissolve)
Discussion