私は、回転ディスクタイプのレイアウトを組み込むためにナビゲーションコントローラを実装しました(各VCを円内にレイアウトし、全体として回転して順番に表示することを想像してください)。コントローラは以下のように、カスタム遷移クラスを使用するように構成されている: -Swift 3のカスタムトランジションが正しく翻訳されない
import UIKit class RotaryTransition: NSObject, UIViewControllerAnimatedTransitioning { let isPresenting :Bool let duration :TimeInterval = 0.5 let animationDuration: TimeInterval = 0.7 let delay: TimeInterval = 0 let damping: CGFloat = 1.4 let spring: CGFloat = 6.0 init(isPresenting: Bool) { self.isPresenting = isPresenting super.init() } func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { //Get references to the view hierarchy let fromViewController: UIViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)! let toViewController: UIViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)! let sourceRect: CGRect = transitionContext.initialFrame(for: fromViewController) let containerView: UIView = transitionContext.containerView if self.isPresenting { // Push //1. Settings for the fromVC ............................ // fromViewController.view.frame = sourceRect fromViewController.view.layer.anchorPoint = CGPoint(x: 0.5, y: 3); fromViewController.view.layer.position = CGPoint(x: fromViewController.view.frame.size.width/2, y: fromViewController.view.frame.size.height * 3); //2. Setup toVC view........................... containerView.insertSubview(toViewController.view, belowSubview:fromViewController.view) toViewController.view.layer.anchorPoint = CGPoint(x: 0.5, y: 3); toViewController.view.layer.position = CGPoint(x: toViewController.view.frame.size.width/2, y: toViewController.view.frame.size.height * 3); toViewController.view.transform = CGAffineTransform(rotationAngle: 15 * CGFloat(M_PI/180)); //3. Perform the animation............................... UIView.animate(withDuration: animationDuration, delay:delay, usingSpringWithDamping: damping, initialSpringVelocity: spring, options: [], animations: { fromViewController.view.transform = CGAffineTransform(rotationAngle: -15 * CGFloat(M_PI/180)); toViewController.view.transform = CGAffineTransform(rotationAngle: 0); }, completion: { (animated: Bool) ->() in transitionContext.completeTransition(true) }) } else { // Pop //1. Settings for the fromVC ............................ fromViewController.view.frame = sourceRect fromViewController.view.layer.anchorPoint = CGPoint(x: 0.5, y: 3); fromViewController.view.layer.position = CGPoint(x: fromViewController.view.frame.size.width/2, y: fromViewController.view.frame.size.height * 3); //2. Setup toVC view........................... // toViewController.view.frame = transitionContext.finalFrame(for: toViewController) toViewController.view.layer.anchorPoint = CGPoint(x: 0.5, y: 3); toViewController.view.layer.position = CGPoint(x: toViewController.view.frame.size.width/2, y: toViewController.view.frame.size.height * 3); toViewController.view.transform = CGAffineTransform(rotationAngle: -15 * CGFloat(M_PI/180)); containerView.insertSubview(toViewController.view, belowSubview:fromViewController.view) //3. Perform the animation............................... UIView.animate(withDuration: animationDuration, delay:delay, usingSpringWithDamping: damping, initialSpringVelocity: spring, options: [], animations: { fromViewController.view.transform = CGAffineTransform(rotationAngle: 15 * CGFloat(M_PI/180)); toViewController.view.transform = CGAffineTransform(rotationAngle: 0); }, completion: { //When the animation is completed call completeTransition (animated: Bool) ->() in transitionContext.completeTransition(true) }) } } func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { return duration; } }
ビューが移動する方法の表現は、2つの赤色の領域...以下の図に表示され、後に説明するように、問題である
。プレゼンテーション(プッシュ)翻訳はうまく動作する - 1と3への2つの移動は2に移動する。しかし、解消(ポップ)変換は行われないので、解散するVCは外見上正しく外に出る(2は3に移動する) (前の)VCが間違った場所に到着するか、フレームのサイズが正しくない場合...
クラスがそのままでは、2は3(正しく)に移動しますが、1は4に移動しますビューのサイズは正しく設定されていますが、意図した場所から見かけ上任意の距離だけずれているようです。私は以来、さまざまなソリューションを試してきました。私は(コードでコメント)次の行を追加しようとしたポップセクションで
: -
toViewController.view.frame = transitionContext.finalFrame(for: toViewController)
...しかしVCは現在、縮小されてしまう(1~5移動)。誰かが私が作っている可能性のある愚かなエラーを見ることができることを願っています。私は単純にプッシュセクションをポップセクションに複製しようとしましたが(そしてすべてを逆にする)、うまくいきませんでした! FYI
... UINavigationControllerへの移行をフックアップする方法を知っておく必要がもの -
...次の関数と一緒に、あなたのナビゲーションコントローラに
func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { let transition: SwingTransition = SwingTransition.init(isPresenting: (operation == .push ? true : false)) return transition; }をUINavigationControllerDelegateを追加します。下の図は、どのようにすべてを示しビューは同じ起点を共有します(翻訳の場合)。目的は、各VCを動かすリボルバーバレルの錯覚を見せることです。上部中央のビューはビューウィンドウを表し、スタック内の3番目のビューを示します。貧しいビジュアルのための謝罪...
コードレビュー_and_問題解決、素敵な仕事! – jrturton
これは、私が望んでいた答えのように見えます。それはとても近いです...悲しいことに、遷移は回転するディスクにビューが固定されているという錯覚を破壊し、異なる場所から発生しているようです。アニメーションを遅くし、いくつかの奇妙な理由、左に移動するビューはビューの右のどこかから始まり、右からのビューは左のどこかに由来します。私は半分の幅で追加しようとしましたが、効果がないようです。 – NickSaintJohn
ビューはリボルバーの箇条書きで、銃身は表示窓ですと想像してください。それらは同じ翻訳元から回転する必要があります。私はまだ微調整しようとしていますが、どこにも行きませんでした。 – NickSaintJohn