Navegación deslizable similar a Snapchat entre vistas en Xcode 6 y Swift)

He estado intentando implementar la navigation deslizable entre View Controllers en mi aplicación usando el reconocimiento de gestos Swipe y el controller de navigation integrado, pero no se ve ni siquiera cerca de la navigation de Snapchat.

¿Cuál sería la forma más eficiente y adecuada de implementar dicha funcionalidad?

Soy muy novato en Swift y en la progtwigción realmente, y agradecería cualquier comentario útil.

La versión corta es usar un controller de vista de contenedor con una vista de desplazamiento dentro del controller. A continuación, crea controlleres de vista separados para cada pantalla que deseas en la aplicación, y haz que esos controlleres de vista vean el controller de vista de contenedor.

Aquí puede encontrar un repository de github con código de ejemplo.

Necesitas un control de página. Esto fue originalmente para mostrar tutoriales y cosas así, pero también puedes poner los controlleres de visualización allí. Hay montones de tutoriales por ahí y, esencialmente, tiene que aplicar un poco de lógica para decirle al progtwig qué controller de vista mostrar después.

Este es un ejemplo bastante avanzado, pero podría ser de ayuda para usted:

https://github.com/cwRichardKim/RKSwipeBetweenViewControllers

No me gusta la versión dada por lbrendanl porque no usa restricciones. No podemos personalizarlo como queramos. Aquí está la misma versión pero con restricciones:

scrollView es un IBOutlet pined al controller con 4 restricciones con una constante a 0 en cada lado a la vista del controller.

contentView también es una IBOutlet agregada como subvista de scrollView pined a scrollView con 4 restricciones con una constante a 0 en cada lado. También tiene una restricción de altura igual y una restricción de ancho igual. La restricción igual de ancho se elimina en el time de ejecución y solo sirve para calmar el IB. Esta vista representa la vista de contenido de scrollView.

ACTUALIZACIÓN iOS 9

  func setupDetailViewControllers() { var previousController: UIViewController? for controller in self.controllers { addChildViewController(controller) addControllerInContentView(controller, previousController: previousController) controller.didMoveToParentViewController(self) previousController = controller } } func addControllerInContentView(controller: UIViewController, previousController: UIViewController?) { contentView.addSubview(controller.view) controller.view.translatesAutoresizingMaskIntoConstraints = false // top controller.view.topAnchor.constraintEqualToAnchor(contentView.topAnchor).active = true // bottom controller.view.bottomAnchor.constraintEqualToAnchor(contentView.bottomAnchor).active = true // trailing trailingContentViewConstraint?.active = false trailingContentViewConstraint = controller.view.trailingAnchor.constraintEqualToAnchor(contentView.trailingAnchor) trailingContentViewConstraint?.active = true // leading let leadingAnchor = previousController?.view.trailingAnchor ?? contentView.leadingAnchor controller.view.leadingAnchor.constraintEqualToAnchor(leadingAnchor).active = true // width controller.view.widthAnchor.constraintEqualToAnchor(scrollView.widthAnchor).active = true } 

RESPUESTA ANTERIOR

  class ContainerViewController: UIViewController { @IBOutlet var scrollView: UIScrollView! @IBOutlet var contentView: UIView! // A strong reference to the width contraint of the contentView var contentViewConstraint: NSLayoutConstraint! // A computed version of this reference var computedContentViewConstraint: NSLayoutConstraint { return NSLayoutConstraint(item: contentView, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: scrollView, attribute: .Width, multiplier: CGFloat(controllers.count + 1), constant: 0) } // The list of controllers currently present in the scrollView var controllers = [UIViewController]() override func viewDidLoad() { super.viewDidLoad() initScrollView() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } func initScrollView(){ contentView.setTranslatesAutoresizingMaskIntoConstraints(false) contentViewConstraint = computedContentViewConstraint view.addConstraint(contentViewConstraint) // Adding all the controllers you want in the scrollView let controller1 = storyboard!.instantiateViewControllerWithIdentifier("AStoryboardID") as! AnUIControllerViewSubclass addToScrollViewNewController(controller) let controller2 = storyboard!.instantiateViewControllerWithIdentifier("AnotherStoryboardID") as! AnotherUIControllerViewSubclass addToScrollViewNewController(controller2) } // The main method, adds the controller in the scrollView at the left of the previous controller added func addToScrollViewNewController(controller: UIViewController) { self.addChildViewController(controller) contentView.addSubview(controller.view) controller.view.setTranslatesAutoresizingMaskIntoConstraints(false) // Setting all the constraints let bottomConstraint = NSLayoutConstraint(item: contentView, attribute: .Bottom, relatedBy: .Equal, toItem: controller.view, attribute: .Bottom, multiplier: 1.0, constant: 0) let topConstraint = NSLayoutConstraint(item: contentView, attribute: .Top, relatedBy: .Equal, toItem: controller.view, attribute: .Top, multiplier: 1.0, constant: 0) let widthConstraint = NSLayoutConstraint(item: controller.view, attribute: .Width, relatedBy: .Equal, toItem: scrollView, attribute: .Width, multiplier: 1.0, constant: 0) var trailingConstraint: NSLayoutConstraint! if controllers.isEmpty { // Since it's the first one, the trailing constraint is from the controller view to the contentView trailingConstraint = NSLayoutConstraint(item: contentView, attribute: .Trailing, relatedBy: .Equal, toItem: controller.view, attribute: .Trailing, multiplier: 1.0, constant: 0) } else { trailingConstraint = NSLayoutConstraint(item: controllers.last!.view, attribute: .Leading, relatedBy: .Equal, toItem: controller.view, attribute: .Trailing, multiplier: 1.0, constant: 0) } // Setting the new width constraint of the contentView view.removeConstraint(contentViewConstraint) contentViewConstraint = computedContentViewConstraint // Adding all the constraints to the view hierarchy view.addConstraint(contentViewConstraint) contentView.addConstraints([bottomConstraint, topConstraint, trailingConstraint]) scrollView.addConstraints([widthConstraint]) controller.didMoveToParentViewController(self) // Finally adding the controller in the list of controllers controllers.append(controller) } } 

He usado la versión de lbrendanl en el pasado. Ahora prefiero este. Déjame saber lo que piensas de él.

Sugiero usar UIPageViewController y esconder la barra de puntos al eliminar estos methods:

 presentationCountForPageViewController presentationIndexForPageViewController 

Aquí hay un buen tutorial:

https://www.youtube.com/watch?v=8bltsDG2ENQ

Aquí hay un excelente repago para esto:

https://github.com/goktugyil/EZSwipeController

Vista de desplazamiento paginado, no un PageViewController en el caso de Snapchat.

Puede intentar usar CATransition para crear la animation CATransition . Aquí hay un ejemplo de cómo puede pasar de una vista a otra:

  UIView *parentView = [self.view superview]; CATransition *animation = [CATransition animation]; [animation setDuration:0.25]; [animation setType:kCATransitionPush]; [animation setSubtype:kCATransitionFromLeft]; [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; [parentView addSubview:yourSecondViewController.view]; [self.view removeFromSuperview]; [[theParentView layer] addAnimation:animation forKey:@"showSecondViewController"]; 

Encontré parte de ese código aquí: ¿Cómo puedo implementar una animation deslizar / deslizar entre vistas?

Tenía un requisito similar, inicialmente implementado con PageController , pero luego lo cambié a UICollectionView donde cada celda es de pantalla completa y el desplazamiento se establece en horizontal.