Как представить контроллер вида справа налево в 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
это легко построить свой навигационный контроллер, если вы предпочитаетевам действительно даже не нужно держать переменную в любом месте, как
.navigationController
is всегда в наличии, как свойство-легко.действительно, как только у вас есть 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]