質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

1715閲覧

フェードインするアニメーションを実装したい

Ka_ya_

総合スコア31

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2020/05/17 06:05

質問失礼します。

ログインボタンを押下したらストーリーボードの画像の様にフェードインして
画面遷移をするアニメーションをライブラリは使用せずに実装したいと思い、
下記サイトを参考にコードを記載してみたのですが、アニメーション処理が呼び出されず、
セグエで設定してあるpresent modallyで遷移してしまいます。
これは何が原因なのでしょうか。

また、アニメーションの移動処理に関してなのですが、コード内に記載のある
containerView.convert(firstViewController.firstImageView.frame, from: firstViewController.firstImageView.superview)

containerView.convert(secondViewController.secondImageView.frame, from: secondViewController.view)
といった引数の記載方法で、どうやって位置が指定されているのかが理解出来ませんでした。

どなたかご教授いただけますと嬉しいです。
よろしくお願い致します。

参考サイト
https://dev.classmethod.jp/articles/ios-custom-transition-zoom/

・遷移元のビューコントローラー

Swift

1import UIKit 2 3class ViewController: UIViewController { 4 5 @IBOutlet weak var firstImageView: UIImageView! 6 7 override func viewDidLoad() { 8 super.viewDidLoad() 9 10 } 11 }

・遷移先のビューコントローラー

Swift

1import UIKit 2 3class TopViewController: UIViewController, UIViewControllerTransitioningDelegate { 4 5 @IBOutlet weak var secondImageView: UIImageView! 6 //アニメーションのインスタンス生成 7 let loginTransition = LoginTransition() 8 9 10 override func viewDidLoad() { 11 12 super.viewDidLoad() 13 self.transitioningDelegate = self 14 } 15 16 @IBAction func backButton(_ sender: Any) { 17 18 dismiss(animated: true, completion: nil) 19 } 20 21 22 //画面遷移してきた時のアニメーション処理 23 func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? { 24 25 return loginTransition 26 } 27}

・アニメーション用のクラス

Swift

1import UIKit 2 3class LoginTransition: NSObject, UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning { 4 5 //アニメーションにかかる時間を設定する 6 func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { 7 return 1 8 } 9 10 //遷移時のアニメーションを設定する 11 func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { 12 13 //遷移先・遷移元ビューの情報を引数にしてアニメーションを呼び出す 14 presentTransition(transitionContext: transitionContext) 15 } 16 17 //アニメーションの内容を設定する 18 func presentTransition(transitionContext: UIViewControllerContextTransitioning) { 19 20 /// 遷移元ビューコントローラー 21 let firstViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from) as! ViewController 22 /// 遷移先ビューコントローラー 23 let secondViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) as! TopViewController 24 ///コンテナビュー 25 let containerView = transitionContext.containerView 26 27 //遷移後のビューコントローラーを、予め最後の位置まで移動完了させ非表示にする 28 secondViewController.view.frame = transitionContext.finalFrame(for: secondViewController) 29 secondViewController.view.alpha = 0 30 //遷移後のimageは、アニメーションが完了するまで非表示にする 31 secondViewController.secondImageView.isHidden = true 32 // 遷移元のセルのイメージビューを非表示にする 33 firstViewController.firstImageView.isHidden = true 34 35 // 遷移元のセルのイメージビューからアニメーション用のビューを作成 36 let animationView = UIImageView(image: firstViewController.firstImageView.image) 37 //アニメーションビューの開始位置を指定している??←アニメーションの位置の指定方法が分からない 38 animationView.frame = containerView.convert(firstViewController.firstImageView.frame, from: firstViewController.firstImageView.superview) 39 40 // 遷移コンテナに、遷移後のビューと、アニメーション用のビューを追加する 41 containerView.addSubview(secondViewController.view) 42 containerView.addSubview(animationView) 43 44 //アニメーションを実装する(引数に秒数・アニメーションのクロージャ・完了後のクロージャを設定する) 45 UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: { 46 // 遷移後のビューを徐々に表示する 47 secondViewController.view.alpha = 1.0 48 // アニメーション用のビューを、遷移後のイメージの位置までアニメーションする←アニメーションの位置の指定方法が分からない 49 animationView.frame = containerView.convert(secondViewController.secondImageView.frame, from: secondViewController.view) 50 }, completion: { 51 //アニメーションが終了した後のクロージャ 52 finished in 53 // 遷移後のイメージを表示する 54 secondViewController.secondImageView.isHidden = false 55 // 遷移前のビューの非表示を元に戻す 56 firstViewController.firstImageView.isHidden = true 57 // アニメーション用のビューを削除する 58 animationView.removeFromSuperview() 59 transitionContext.completeTransition(true) 60 }) 61 } 62}

ストーリーボード

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

フェードイン?の部分が表現していることがわかりませんが、
fromとtoの2枚のviewControllerをアニメーションさせて入れ替える処理を書けばいいと思います。
その際の大きさ(frame)のもとをcontainerから取得するイメージで書いてください。

storyboard上で矢印を引いて遷移する方法への適用方法は私わかりません。

簡単なサンプルを置いておきます。

イメージ説明

サンプル内のカスタムトランジッション部分/遷移時の処理・復帰時の処理の部分だけいじってみてください。

swift

1 2import UIKit 3 4class GreenVC: UIViewController { 5 6 let customTransition = CustomTransition() 7 8 override func viewDidLoad() { 9 super.viewDidLoad() 10 } 11 12 // 遷移処理 13 @IBAction func transitionToOrange(_ sender: Any) { 14 15 let toVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(identifier: "OrangeVC") 16 17 toVC.modalPresentationStyle = .overCurrentContext 18 toVC.transitioningDelegate = customTransition 19 20 present(toVC, animated: true, completion: nil) 21 } 22 23 // 戻ってきたときの処理 24 @IBAction func backFromOrangeVC(segue: UIStoryboardSegue) { 25 26 } 27 28} 29 30class OrangeVC: UIViewController { 31 32 override func viewDidLoad() { 33 super.viewDidLoad() 34 // Do any additional setup after loading the view. 35 } 36 37 @IBAction func btnDidTap(_ sender: Any) { 38 performSegue(withIdentifier: "BacktoGreenVC", sender: nil) 39 40 } 41 42} 43 44 45class CustomTransition: NSObject, UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning { 46 47 fileprivate var isPresent: Bool = false 48 fileprivate let duration : TimeInterval = 0.6 49 50 func animationController(forPresented presented: UIViewController, 51 presenting: UIViewController, 52 source: UIViewController) -> UIViewControllerAnimatedTransitioning? 53 { 54 isPresent = true 55 return self 56 } 57 58 func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { 59 isPresent = false 60 return self 61 } 62 63 func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { 64 return duration 65 } 66 67 func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { 68 if isPresent { 69 animatePresentTransition(transitionContext: transitionContext) 70 } else { 71 animateDissmissalTransition(transitionContext: transitionContext) 72 } 73 } 74 75 // 遷移時の処理 76 func animatePresentTransition(transitionContext: UIViewControllerContextTransitioning) { 77 78 // from: 遷移元, to:遷移先, container: 枠?を取得する 79 let from: UIViewController! 80 = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from) 81 let to: UIViewController! 82 = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) 83 let container: UIView! = transitionContext.containerView 84 85 // viewを変形させる設定 86 let transform: CGAffineTransform = CGAffineTransform(scaleX: 0.3, y: 0.3) 87 88 // 遷移先画面(to)を用意する 89 to.view.frame = container.frame 90 to.view.alpha = .zero 91 container.insertSubview(to.view, belowSubview: from.view) 92 to.view.transform = transform 93 94 // アニメーションしながら遷移元と遷移先を入れ替える 95 UIView.animate(withDuration: duration, animations: { 96 to.view.transform = .identity 97 to.view.alpha = 1.0 98 }, completion: {_ in 99 from.removeFromParent() 100 transitionContext.completeTransition(true) 101 }) 102 } 103 104 // 復帰時の処理 105 func animateDissmissalTransition(transitionContext: UIViewControllerContextTransitioning) { 106 107 // from: 遷移元, to:遷移先, container: 枠?を取得する 108 let from: UIViewController! 109 = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from) 110 let to: UIViewController! 111 = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) 112 let container: UIView! = transitionContext.containerView 113 114 // viewを変形させる設定 115 let transform: CGAffineTransform = CGAffineTransform(scaleX: 0.3, y: 0.3) 116 117 // 遷移先画面(to)を用意する 118 to.view.frame = container.frame 119 container.insertSubview(from.view, belowSubview: to.view) 120 121 // アニメーションしながら遷移元と遷移先を入れ替える 122 UIView.animate(withDuration: duration, animations: { 123 from.view.transform = transform 124 from.view.alpha = .zero 125 }, completion: {_ in 126 from.removeFromParent() 127 transitionContext.completeTransition(true) 128 }) 129 } 130} 131 132

投稿2020/05/17 07:49

編集2020/05/17 07:51
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Ka_ya_

2020/05/17 08:46

tyobigorouさん、丁寧にご回答下さりありがとうございます。 説明が下手で申し訳ありません。 フェードインというのは遷移元に配置されているimageViewの画像を、 遷移する際に縮小する様なアニメーションで遷移先のimageViewに表示させたいという意味でした。 コメント付きのサンプルをいただけて処理の内容がとても分かりやすく、 色々と調べて混乱してしまっていた遷移アニメーションの流れがお陰様で良く分かりました^^ 早速自分のコードにも反映させようと思い、ストーリーボードのセグエを削除して ストーリーボードIDで遷移する様に遷移元のボタン押下時の処理を下記のように書き換えてみたのですが、 やはり通常のpresent処理になってしまいました。 処理の流れをprintで確認してみたところ、カスタムアニメーションクラスの中に入っていない状態です。 この記載を質問時のコードに追加するだけではアニメーションクラスの処理には入らないのでしょうか。 たびたびお手数をおかけしますが、 よろしければご確認お願い致します。 import UIKit class ViewController: UIViewController, UIViewControllerTransitioningDelegate { @IBOutlet weak var firstImageView: UIImageView! let loginTransition = LoginTransition() @IBAction func loginButton(_ sender: Any) { let topVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(identifier: "top") topVC.modalPresentationStyle = .overCurrentContext topVC.transitioningDelegate = loginTransition present(topVC, animated: true, completion: nil) }
退会済みユーザー

退会済みユーザー

2020/05/17 08:51

topVC.transitioningDelegate = loginTransitionをコメントアウトして通常の遷移はできるのでしょうか? ご自身で2画面のサンプルを作ることをおすすめします。
Ka_ya_

2020/05/17 09:09

tyobigorouさん、ご確認いただきありがとうございます。 topVC.transitioningDelegate = loginTransitionをコメントアウトしても通常の遷移は可能でした。 topVC.modalPresentationStyle = .overCurrentContextなどは変更すると反映される為、 アニメーション処理の呼び出しに失敗しているようです>< 丁寧にサンプルを作成していただいたのにすみません。 クラスを分けている事などによって教えていただいたコードと相違が発生しているかもしれないので、 もう一度コードをしっかりと見直してみようと思います。
Ka_ya_

2020/05/18 04:42

tyobigorouさん、昨日は丁寧にご回答下さりありがとうございました^^ あれから色々と調べながら御教授いただいたコードと照らし合わせて見直したところ、 ・funcの記載方法がアップル公式の最新のものではなかった ・遷移先でDelegateを設定していた 上記が問題だったようで、それらを修正したらアニメーションクラスに入る事が出来ました! お手数をおかけしてすみません、サンプルのお陰で本当に助かりました^^ アニメーションの作成自体も頑張ろうと思いますっ!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問