滑动边栏菜单IOS 8斯威夫特

有什么办法可以在没有任何第三方库的情况下在iOS Swift中实现幻灯片边栏菜单(如Facebook应用程序)? 我寻找解决scheme,但我只build立了在Objective-C中实现的这个function。

我相信你可以开始在iOS8中大幅更新的UISplitViewController。 观看会议iOS8中的View Controller进步以及使用UIKit构build适应性应用程序以了解详细信息。 他们提供第二个会话的代码示例 (但不是第一个:/)。 在这一点上,我觉得这是基于iOS8中的分割视图控制器的这种UI。

更新:看起来他们谈论的所有API都没有登陆。 例如,在video中提到的当前beta4中,并没有提供浓缩BonesOnSwipe。

更新 :请考虑使用我更新的答案,而不是这一个。 滚动视图/容器视图方法有很多边缘情况,可以通过使用“自定义视图控制器转换”来避免。

我看遍了各地的Swift菜单解决scheme,不需要库。 最后创build了一个我自己的教程,与Fengson的方法非常相似:

在这里输入图像说明

这里有一些要点:

  • 创build一个scrollview ,该scrollview将处理菜单滑动运动以及平移手势
  • scrollview视图中并排放置两个container视图。 容器允许您embedded顶级控制器。
  • scrollview ,设置paging enabled但禁用bounces 。 这将强制滑出到打开或closures状态
  • 在左边的容器中embed一个UITableViewController
  • embed UITabBarController embed到正确的容器中
  • 在正确的container ,添加0.8的运行时属性layer.shadowOpacity 。 这给你一个没有任何代码的免费阴影分隔符。
  • 添加一个菜单button。 您可以使用NSNotificationCenterscrollview进行通信
  • 对于秘密成分:使用scrollView.setContentOffset.x来照顾菜单的实际打开和closures

这是一个带有左侧滑出菜单的标签栏应用程序的工作示例项目,包括屏幕截图和说明。

https://github.com/ThornTechPublic/LeftSlideoutMenu

随着一个更通用的解释如何工作:

http://www.thorntech.com/2015/06/want-to-implement-a-slideout-menu-in-your-swift-app-heres-how/

滑动iOS7和iOS8的侧栏菜单,以Swift编码。

如果你想在NavigationController级别 (这意味着,在其后面的所有视图控制器):

https://github.com/evnaz/ENSwiftSideMenu

如果你只想在一个ViewController中

video: https : //www.youtube.com/watch?v = qaLiZgUK2T0

源代码: http : //goo.gl/ULWxJh

在这种情况下,为了兼容iOS7,只需添加“添加模糊视图”注释的“if”条件,如下所示:

 if (NSClassFromString("UIVisualEffectView") != nil) { // Add blur view let blurView:UIVisualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: UIBlurEffectStyle.Light)) blurView.frame = sideBarContainerView.bounds sideBarContainerView.addSubview(blurView) } 

我认为使用自定义视图控制器转换是制作滑出菜单的可靠方法:

  • 您可以自定义animation。
  • 过渡是互动的,所以你可以拖动前进和后退。 转换总是结束或回滚,而不会陷入中间状态。
  • 您使用平移手势和屏幕边缘平移手势来驱动交互。 这意味着您可以策略性地放置它们,以最大限度地减less与水平手势内容的冲突。
  • 您不必诉诸于容器视图。 这意味着您的应用程序体系结构更平坦,您可以使用协议委托而不是NSNotifications。
  • 一次只有一个ViewController处于活动状态。 快照用于给出屏幕上有第二个VC的错觉。

互动幻灯片动画GIF

自定义视图控制器转换起初很难学习(至less对我来说是这样)。 我写了一篇关于如何创build交互式滑出菜单的博客文章 ,并尽可能使其尽可能地容易理解。

你也可以直接跳到GitHub上的代码 。

在很高的层面上,这是如何工作的:

  1. 您打开滑出菜单作为模式。
  2. 您可以使用UIViewControllerAnimatedTransitioning协议为当前创build自定义animation并消除转场。 animation中使用快照来表示主视图控制器。
  3. 您创build泛姿态识别器以交互方式呈现/解除模态。
  4. 将Pan Gesture事件连接到UIPercentDrivenInteractiveTransition对象,以保持转换与用户的移动同步。
  5. 呈现控制器采用UIViewControllerTransitioningDelegate协议,连接所有的自定义animation和交互式转换。

我实际上有一个使用滚动视图/容器视图的线程上的回答。 这种方法对于原型是可以的,但是在准备好应用程序的时候遇到了很多边缘情况和bug。 花每个星期回复博客评论和修复边缘案例是什么激励我写这个主题的第二篇博客文章。

这是另一个SideMenu库,我添加到混合: https : //github.com/jonkykong/SideMenu 。

受Facebook启发的Swift iOS中简单的侧面菜单控制。 右侧和左侧。 不需要编码。

  • 它可以在没有一行代码的故事板中实现。
  • 四种标准的animation风格可供select(如果你想变得奇怪,甚至是视差)。
  • 高度自定义,无需编写大量的自定义代码。
  • 支持通过单个手势在两侧的侧面菜单之间连续滑动。
  • 全局菜单configuration。 设置一次,并为所有屏幕完成。
  • 菜单可以像任何其他视图控制器一样呈现和解除,因为此控件使用自定义过渡。

这里是我如何做的一个小例子,这个抽屉控件有左,中,右的uiviewcontrollers。 这一个像松散的iPad应用程序,其中一方或另一方是打开的。

 /* To use simply instantiate NVMDrawerController as your root view in your AppDelegate, or in the StoryBoard. Once NVMDrawerController is instantiated, set the drawerSize of the NVMDrawerController, and its leftViewControllerIdentifier, centerViewControllerIdentifier, and rightViewControllerIdentifier to the Storyboard Identifier of the UIViewController you want in the different locations. */ class NVMDrawerController: UIViewController { // This is where you set the drawer size (ie for 1/3rd use 3.0, for 1/5 use 5.0) var drawerSize:CGFloat = 4.0 var leftViewControllerIdentifier:String = "LeftController" var centerViewControllerIdentifier:String = "CenterController" var rightViewControllerIdentifier:String = "RightController" private var _leftViewController:UIViewController? var leftViewController:UIViewController { get{ if let vc = _leftViewController { return vc; } return UIViewController(); } } private var _centerViewController:UIViewController? var centerViewController:UIViewController { get{ if let vc = _centerViewController { return vc; } return UIViewController(); } } private var _rightViewController:UIViewController? var rightViewController:UIViewController { get{ if let vc = _rightViewController { return vc; } return UIViewController(); } } static let NVMDrawerOpenLeft = 0 static let NVMDrawerOpenRight = 1 var openSide:Int { get{ return _openSide; } } private var _openSide:Int = NVMDrawerOpenLeft override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. // Instantiate VC's with storyboard ID's _leftViewController = instantiateViewControllers(leftViewControllerIdentifier) _centerViewController = instantiateViewControllers(centerViewControllerIdentifier) _rightViewController = instantiateViewControllers(rightViewControllerIdentifier) // Call configDrawers() and pass the drawerSize variable. drawDrawers(UIScreen.mainScreen().bounds.size) self.view.addSubview(leftViewController.view) self.view.addSubview(centerViewController.view) self.view.addSubview(rightViewController.view) } override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) { coordinator.animateAlongsideTransition({ (UIViewControllerTransitionCoordinatorContext) -> Void in // This is for beginning of transition self.drawDrawers(size) }, completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in // This is for after transition has completed. }) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } // MARK: - Drawing View func drawDrawers(size:CGSize) { // Calculate Center View's Size let centerWidth = (size.width/drawerSize) * (drawerSize - 1) // Left Drawer leftViewController.view.frame = CGRect(x: 0.0, y: 0.0, width: size.width/drawerSize, height: size.height) // Center Drawer centerViewController.view.frame = CGRect(x: leftViewController.view.frame.width, y: 0.0, width: centerWidth, height: size.height) // Right Drawer rightViewController.view.frame = CGRect(x: centerViewController.view.frame.origin.x + centerViewController.view.frame.size.width, y: 0.0, width: size.width/drawerSize, height: size.height) //rightViewController = rc // Capture the Swipes let swipeRight = UISwipeGestureRecognizer(target: self, action: Selector("swipeRightAction:")) swipeRight.direction = .Right centerViewController.view.addGestureRecognizer(swipeRight) let swipeLeft = UISwipeGestureRecognizer(target: self, action: Selector("swipeLeftAction:")) swipeLeft.direction = .Left centerViewController.view.addGestureRecognizer(swipeLeft) if(openSide == NVMDrawerController.NVMDrawerOpenLeft){ openLeftDrawer() } else{ openRightDrawer() } } // MARK: - Open Drawers func openLeftDrawer() { _openSide = NVMDrawerController.NVMDrawerOpenLeft UIView.animateWithDuration(0.1, delay: 0, options: UIViewAnimationOptions.CurveEaseIn, animations: { () -> Void in // move views here self.view.frame = CGRect(x: 0.0, y: 0.0, width: self.view.bounds.width, height: self.view.bounds.height) }, completion: { finished in }) } func openRightDrawer() { _openSide = NVMDrawerController.NVMDrawerOpenRight UIView.animateWithDuration(0.1, delay: 0, options: UIViewAnimationOptions.CurveEaseIn, animations: { () -> Void in // move views here self.view.frame = CGRect(x: self.view.bounds.origin.x - self.leftViewController.view.bounds.size.width, y: 0.0, width: self.view.bounds.width, height: self.view.bounds.height) }, completion: { finished in }) } // MARK: - Swipe Handling func swipeRightAction(rec: UISwipeGestureRecognizer){ self.openLeftDrawer() } func swipeLeftAction(rec:UISwipeGestureRecognizer){ self.openRightDrawer() } // MARK: - Helpers func instantiateViewControllers(storyboardID: String) -> UIViewController { if let viewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("\(storyboardID)") as? UIViewController{ return viewController; } return UIViewController(); } } 

我已经用两种方式实现了它。
首先使用Scroll View然后使用Container Views

您可以将TableViewController作为一个容器中的菜单,并将TabBarController作为另一个容器中的隐藏选项卡。 按表格视图中的Cell将移动到选项卡栏中的第n个选项卡。

您只需按一下button或一个手势即可为顶部容器设置animation。 那么可能看起来像这样:

在这里输入图像说明

清晰的是,你可以很容易地使用内置的方法添加很酷的效果,比如使用弹簧阻尼对UIView进行animation处理,使其具有逼真的弹性效果。 您也可以将阴影添加到主视图(未添加到图片中),使其看起来像菜单上方的页面。