Как представить контроллер вида справа налево в iOS с помощью Swift
я использую presentViewController, чтобы представить новый экран
let dashboardWorkout = DashboardWorkoutViewController()
presentViewController(dashboardWorkout, animated: true, completion: nil)
это представляет новый экран снизу вверх, но я хочу, чтобы он был представлен справа налево без использования UINavigationController.
Я использую Xib вместо раскадровки, так как я могу это сделать ?
10 ответов:
это не имеет значения, если это
xibилиstoryboardчто вы используете. Как правило, справа налево переход используется, когда вы нажимаете на контроллере вид на ведущей вUINavigiationController.обновление
добавлена функция времени
kCAMediaTimingFunctionEaseInEaseOutпример проекта С Swift 4 реализация добавлена в GitHub
Swift 3 & 4let transition = CATransition() transition.duration = 0.5 transition.type = kCATransitionPush transition.subtype = kCATransitionFromRight transition.timingFunction = CAMediaTimingFunction(name:kCAMediaTimingFunctionEaseInEaseOut) view.window!.layer.add(transition, forKey: kCATransition) present(dashboardWorkout, animated: false, completion: nil)
ObjCCATransition *transition = [[CATransition alloc] init]; transition.duration = 0.5; transition.type = kCATransitionPush; transition.subtype = kCATransitionFromRight; [transition setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; [self.view.window.layer addAnimation:transition forKey:kCATransition]; [self presentViewController:dashboardWorkout animated:false completion:nil];
Swift 2.xlet transition = CATransition() transition.duration = 0.5 transition.type = kCATransitionPush transition.subtype = kCATransitionFromRight transition.timingFunction = CAMediaTimingFunction(name:kCAMediaTimingFunctionEaseInEaseOut) view.window!.layer.addAnimation(transition, forKey: kCATransition) presentViewController(dashboardWorkout, animated: false, completion: nil)кажется на
presentViewControllerметод на самом деле не имеет значения в этом случае пользовательского перехода. Он может иметь любое значение, либоtrueилиfalse.
полный код для present / dismiss, Swift 3
extension UIViewController { func presentDetail(_ viewControllerToPresent: UIViewController) { let transition = CATransition() transition.duration = 0.25 transition.type = kCATransitionPush transition.subtype = kCATransitionFromRight self.view.window!.layer.add(transition, forKey: kCATransition) present(viewControllerToPresent, animated: false) } func dismissDetail() { let transition = CATransition() transition.duration = 0.25 transition.type = kCATransitionPush transition.subtype = kCATransitionFromLeft self.view.window!.layer.add(transition, forKey: kCATransition) dismiss(animated: false) } }
вы также можете использовать пользовательские темы.
Swift 3
class SegueFromRight: UIStoryboardSegue { override func perform() { let src = self.source let dst = self.destination src.view.superview?.insertSubview(dst.view, aboveSubview: src.view) dst.view.transform = CGAffineTransform(translationX: src.view.frame.size.width, y: 0) UIView.animate(withDuration: 0.25, delay: 0.0, options: UIViewAnimationOptions.curveEaseInOut, animations: { dst.view.transform = CGAffineTransform(translationX: 0, y: 0) }, completion: { finished in src.present(dst, animated: false, completion: nil) } ) } }
попробуйте это,
let animation = CATransition() animation.duration = 0.5 animation.type = kCATransitionPush animation.subtype = kCATransitionFromRight animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) vc.view.layer.addAnimation(animation, forKey: "SwitchToView") self.presentViewController(vc, animated: false, completion: nil)здесь
vcэто viewcontroller,dashboardWorkoutв вашем случае.
если вы хотите использовать метод CATransition "быстрого исправления"....
class AA: UIViewController func goToBB { let bb = .. instantiateViewcontroller, storyboard etc .. as! AlreadyOnboardLogin let tr = CATransition() tr.duration = 0.25 tr.type = kCATransitionMoveIn // use "MoveIn" here tr.subtype = kCATransitionFromRight view.window!.layer.add(tr, forKey: kCATransition) present(bb, animated: false) bb.delegate, etc = set any other needed values }и потом ...
func dismissingBB() { let tr = CATransition() tr.duration = 0.25 tr.type = kCATransitionReveal // use "Reveal" here tr.subtype = kCATransitionFromLeft view.window!.layer.add(tr, forKey: kCATransition) dismiss(self) .. or dismiss(bb), or whatever }все это, к сожалению, не совсем правильно :(
CATransitionна самом деле не создан для выполнения этой работы.Примечание Вы получите раздражает плавный переход в черный которых, к сожалению, разрушает эффект.
многие разработчики (как и я) действительно не любят использовать
NavigationController. Часто, он более гибок к просто присутствует в специальной манере, как вы идете, особенно для необычных и сложных приложений. Тем не менее, это не трудно "добавить" навигационный контроллер.
просто на раскадровке, перейдите к записи VC и нажмите кнопку "embed -> in nav controller". Вот именно. Или,
in
didFinishLaunchingWithOptionsэто легко построить свой навигационный контроллер, если вы предпочитаетевам действительно даже не нужно держать переменную в любом месте, как
.navigationControlleris всегда в наличии, как свойство-легко.действительно, как только у вас есть navigationController, это тривиально делать переходы между экранами,
let nextScreen = instantiateViewController etc as! NextScreen navigationController? .pushViewController(nextScreen, animated: true)и
pop.что однако только дает вам стандартное яблоко" двойной толчок " эффект...
(старый соскальзывает на более низкой скорости, как новый скользит дальше.)
вообще и удивительно, вы обычно должны приложить усилия, чтобы сделать полный заказ переход.
даже если вы просто хотите самый простой, наиболее распространенный переход перемещения/перемещения, вам нужно сделать полный пользовательский переход.
к счастью, для этого есть некоторые вырезать и вставить шаблонный код на ОК... https://stackoverflow.com/a/48081504/294884 . С Новым 2018 годом!
прочитайте все ответы и не можете увидеть правильное решение. Правильный способ сделать это-сделать пользовательский UIViewControllerAnimatedTransitioning для представленного делегата VC.
таким образом, он предполагает сделать больше шагов, но результат более настраиваемый и не имеет побочных эффектов, таких как перемещение из вида вместе с представленным видом.
Итак, предположим, что у вас есть какой-то ViewController, и есть метод для представления
var presentTransition: UIViewControllerAnimatedTransitioning? var dismissTransition: UIViewControllerAnimatedTransitioning? func showSettings(animated: Bool) { let vc = ... create new vc to present presentTransition = RightToLeftTransition() dismissTransition = LeftToRightTransition() vc.modalPresentationStyle = .custom vc.transitioningDelegate = self present(vc, animated: true, completion: { [weak self] in self?.presentTransition = nil }) }
presentTransitionиdismissTransitionиспользуется для анимация контроллеров вида. Таким образом, вы принимаете ваш ViewController кUIViewControllerTransitioningDelegate:extension ViewController: UIViewControllerTransitioningDelegate { func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { return presentTransition } func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { return dismissTransition } }таким образом, последний шаг заключается в создании пользовательского перехода:
class RightToLeftTransition: NSObject, UIViewControllerAnimatedTransitioning { let duration: TimeInterval = 0.25 func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { return duration } func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { let container = transitionContext.containerView let toView = transitionContext.view(forKey: .to)! container.addSubview(toView) toView.frame.origin = CGPoint(x: toView.frame.width, y: 0) UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut, animations: { toView.frame.origin = CGPoint(x: 0, y: 0) }, completion: { _ in transitionContext.completeTransition(true) }) } } class LeftToRightTransition: NSObject, UIViewControllerAnimatedTransitioning { let duration: TimeInterval = 0.25 func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { return duration } func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { let container = transitionContext.containerView let fromView = transitionContext.view(forKey: .from)! container.addSubview(fromView) fromView.frame.origin = .zero UIView.animate(withDuration: duration, delay: 0, options: .curveEaseIn, animations: { fromView.frame.origin = CGPoint(x: fromView.frame.width, y: 0) }, completion: { _ in fromView.removeFromSuperview() transitionContext.completeTransition(true) }) } }в этом контроллере представления кода представлен в текущем контексте, вы можете сделать свои настройки с этой точки. Также вы можете увидеть custom
UIPresentationControllerтакже полезно (передать с помощьюUIViewControllerTransitioningDelegate)
попробуйте это.
let transition: CATransition = CATransition() transition.duration = 0.3 transition.type = kCATransitionReveal transition.subtype = kCATransitionFromLeft self.view.window!.layer.addAnimation(transition, forKey: nil) self.dismissViewControllerAnimated(false, completion: nil)
У меня есть лучшее решение, которое сработало для меня, если вы хотите сохранить классическую анимацию Apple, не видя этого "черного" перехода, который вы видите с помощью CATransition(). Просто используйте метод popToViewController.
вы можете искать viewController вам нужно в
self.navigationController.viewControllers // Array of VC that contains all VC of current stackвы можете искать viewController вам нужно, ища его restorationIdentifier.
будьте осторожны: например, если вы перемещаетесь через 3 контроллера вида, и когда прибудете к последнему вы хотите поп первым. В этом случае вы потеряете ссылку на эффективный контроллер второго вида, потому что popToViewController перезаписал его. Кстати, есть решение: вы можете легко сохранить перед popToViewcontroller, VC вам понадобится позже. Это сработало для меня очень хорошо.
присутствует контроллер вида справа налево в iOS с помощью Swift
func FrkTransition() { let transition = CATransition() transition.duration = 2 transition.type = kCATransitionPush transitioningLayer.add(transition,forKey: "transition") // Transition to "blue" state transitioningLayer.backgroundColor = UIColor.blue.cgColor transitioningLayer.string = "Blue" }Refrence By: [https://developer.apple.com/documentation/quartzcore/catransition][1]