我一直在尝试使用滑动手势识别器和嵌入式导航控制器在我的应用中的视图控制器之间实现滑动导航,但它看起来并不接近Snapchat的导航。
实施此类功能的最有效和最恰当的方式是什么?
我真的很喜欢Swift和编程,我很感激所有有用的评论。
答案 0 :(得分:20)
简短版本是在控制器内部使用带有滚动视图的容器视图控制器。然后,您可以为应用程序中的每个屏幕创建单独的视图控制器,并使这些视图控制器成为可能。父容器视图控制器。
可以找到带有示例代码的github仓库,here。
答案 1 :(得分:8)
您需要一个pageviewcontroller。这最初是为了展示教程和内容,但你也可以将视图控制器放在那里。有大量的教程,基本上你必须应用一些逻辑来告诉程序接下来要显示哪个视图控制器。
这是一个非常先进的例子,但它对你有帮助:
https://github.com/cwRichardKim/RKSwipeBetweenViewControllers
答案 2 :(得分:4)
我不喜欢lbrendanl给出的版本,因为它不使用约束。我们不能像我们想要的那样定制它。这是相同的版本但有约束:
scrollView是一个IBOutlet,它带有4个约束,控制器视图两侧的常量为0。
contentView也是一个IBOutlet,作为scrollView的子视图添加到具有4个约束的scrollView,每个边的常量为0。它还具有相等的高度约束和宽度相等的约束。宽度相等约束在运行时被移除,仅用于冷静IB。此视图表示scrollView的contentView。
更新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
}
以前的答案
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)
}
}
我过去曾使用过lbrendanl的版本。现在我更喜欢这个。告诉我你对它的想法。
答案 3 :(得分:3)
我建议使用UIPageViewController并通过删除这些方法来隐藏点栏:
presentationCountForPageViewController
presentationIndexForPageViewController
这是一个很好的教程:
https://www.youtube.com/watch?v=8bltsDG2ENQ
这是一个很棒的回购:
答案 4 :(得分:1)
分页滚动视图,而不是Snapchat的PageViewController。
答案 5 :(得分:1)
我有类似的要求,最初是使用PageController
实现的,但后来我将其更改为UICollectionView
,其中每个单元格都是全屏,滚动设置为水平。
答案 6 :(得分:0)
您可以尝试使用CATransition
创建滑动动画。以下是如何从一个视图滑动到另一个视图的示例:
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"];
我在这里找到了一些代码:How can I implement a swiping/sliding animation between views?