Swift实现类网易云音乐横向scroll menu切换菜单(二)

从这篇文章准备深入分析scroll menu切换菜单的实现,效果图、框架的github链接可见上一篇文章。

CAPSPageMenu.swift的开头为一个@objc公共协议,这个协议的委托由具体添加该CAPSPageMenu的viewcontroller接受。

    public init (viewControllers: [ UIViewController ], frame: CGRect , options: [ String : AnyObject ]?) {
       
super . init (nibName: nil , bundle: nil )
       
       
controllerArray = viewControllers
       
       
self . view . frame = frame
    }

这是该类的基本初始化方法,viewController为初始化时传入的Controller数组,即通过菜单切换时所展示的若干个viewcontroller;frame为切换菜单scroll menu的大小;options该初始化方法中未被处理。

    public convenience init (viewControllers: [ UIViewController ], frame: CGRect , pageMenuOptions: [ CAPSPageMenuOption ]?) {

}
这是该类在Demo5中所使用的初始化方法,viewcontroller与frame的含义与上个初始化方法相同,pageMenuOptions是一个枚举类型的数组,用于配置切换菜单的各种参数,通过带参数的枚举类型传值确实是我第一次见.. 如下图,只截取部分。

if let options = pageMenuOptions {

            for option in options {

                switch (option) {

                case let .SelectionIndicatorHeight(value):

                    selectionIndicatorHeight = value

                case let .MenuItemSeparatorWidth(value):

                    menuItemSeparatorWidth = value

                case let .ScrollMenuBackgroundColor(value):

                    scrollMenuBackgroundColor = value

                case let .ViewBackgroundColor(value):

                    viewBackgroundColor = value

                case let .BottomMenuHairlineColor(value):

                    bottomMenuHairlineColor = value

                case let .SelectionIndicatorColor(value):

                    selectionIndicatorColor = value

                case let .MenuItemSeparatorColor(value):

                    menuItemSeparatorColor = value

                case let .MenuMargin(value):

                    menuMargin = value

                case let .MenuHeight(value):

                    menuHeight = value



传入的是枚举类型数组,该枚举类型中不同的具体类型代表需要配置的不同方面,每个具体类型中含有一个参数,作为对该方面的具体配置。

比起传入anyobject类型的数组,然后通过index进行配置的方式,好处有:
1.使用枚举类型,避免了使用anyobject所造成的类型模糊
2.每个具体类型在传入时都同时带有该类型的功能描述和配置参数,增强了代码的可读性。

        setUpUserInterface ()
       
       
if menuScrollView . subviews . count == 0 {
           
configureUserInterface ()
        }

这段代码出现在上述第二个初始化方法中,若该页面为第一次加载则需调用configureUserInterface进行页面设置。

    func configureUserInterface() 

该函数实现的主要功能有:
1.为menuScrollView也就是四个按键配置点击手势识别,该View是UIScrollView的实例,调用handleMenuItemTap来判断应该切换到四个界面之中的哪个。
2.通过for循环具体配置menuScrollView的四个MenuItemView,同时在下方显示第一个page。
3.最后的selection indicator是当前选择按钮的下划线。

    func setUpUserInterface()

该函数用于创建用户界面,创建用于装载内容的menuScrollView和controllerScrollView,并将其添加到主view中。

    public func scrollViewDidScroll(scrollView: UIScrollView )

1.判断划动方向,赋值给newScrollDirection,以此来修改currentPageIndex参数,然后调用addPageAtIndex函数将划动后选择的页面加载到controllerScrollView上。
2.加载划动动画显示时所展示出来的部分相邻的viewController页面。
3.调整当前view与划动时相邻view的显示比例。
pagesAddedDictionary [index] = index
这句的作用是注明第index页已被加载,该数组的作用就是记录页面的加载情况。

public func scrollViewDidEndDecelerating(scrollView: UIScrollView )

触摸屏幕并拖拽画面,最后滚动停止时会调用此函数,将其它加载的页面删除,将当前页面设置成划动起始页面,清空记录页面情况的数组。

func scrollViewDidEndTapScrollingAnimation() 
调用以下函数,来自动滚动到想要的位置,此过程中设置有动画效果,停止时,触发上述函数

UIScrollView的setContentOffset:animated: 
UIScrollView的scrollRectToVisible:animated:
UITableView的scrollToRowAtIndexPath:atScrollPosition:animated:
UITableView的selectRowAtIndexPath:animated:scrollPosition:

该函数内容与上一个函数内容相同,完成滚动结束时的收尾工作。

override public func viewDidLayoutSubviews() 

配置controllerScrollView大小、配置selectionIndicatorbar大小、配置menu item大小。

public func moveToPage(index: Int )

该函数在Demo中没有被调用其功能为跳到某一特定Page页面,部分函数功能与前面配置用户界面设置点击时间时所调用的函数handleMenuItemTap相同。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
swift编写简单的左右菜单栏 // // MenuViewController.swift // Menu // // Created by innovane on 14-6-23. // Copyright (c) 2014年 innovane. All rights reserved. // import UIKit let kICSDrawerControllerLeftViewInitialOffset : CGFloat = 60.0 let kICSDrawerControllerDrawerDepth : CGFloat = 200.0 enum ICSDrawerControllerState : Int { case MenuControllerStateOpening case MenuControllerStateClosing } class MenuViewController: UIViewController { //用户点击center var tapGestureRecognizer : UITapGestureRecognizer! // 用户拖动视图 var panGestureRecognizer : UIPanGestureRecognizer! // 用户touch的点位置 var panGestureStartLocation : CGPoint! // 左边控制器 var leftViewController : UIViewController! //中间控制器 var centerViewController : UIViewController! var drawerState : ICSDrawerControllerState! init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) // Custom initialization } override func viewDidLoad() { super.viewDidLoad() self.drawerState = ICSDrawerControllerState.MenuControllerStateClosing; } override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) // 将左边控制器加入导航栏中。 if self.leftViewController != nil{ if (self.leftViewController.view.superview == nil){ self.addChildViewController(self.leftViewController) self.view.insertSubview(self.leftViewController.view, atIndex:0) } } if self.centerViewController != nil{ if (self.centerViewController.view.superview == nil){ self.addChildViewController(self.centerViewController) self.view.addSubview(self.centerViewController.view) } } // 添加用户拖动事件。 self.panGestureRecognizer = UIPanGestureRecognizer() self.panGestureRecognizer.addTarget(self,action:"panGestureRecognized:"); self.centerViewController.view.addGestureRecognizer(self.panGestureRecognizer) } // 用户拖动视图调用代理方法。 func panGestureRecognized(panGestureRecognizer:UIPanGestureRecognizer){ // 用户对视图操控的状态。 var state = panGestureRecognizer.state; var location = panGestureRecognizer.locationInView(self.view) var velocity = panGestureRecognizer.velocityInView(self.view) switch (state) { case UIGestureRecognizerState.Began: // 记录用户开始点击的位置 self.panGestureStartLocation = location; println("Began") break; case UIGestureRecognizerState.Changed: println("Changed") var c = self.centerViewController.view.frame if (panGestureRecognizer.translationInView(self.centerViewController.view).x > 0){ if (self.drawerState == ICSDrawerControllerState.MenuControllerStateClosing){ c.origin.x = location.x - self.panGestureStartLocation.x; } }else if (panGestureRecognizer.translationInView(self.centerViewController.view).x > -kICSDrawerControllerDrawerDepth){ if (self.drawerState == ICSDrawerControllerState.MenuControllerStateOpening){ c.origin.x = panGestureRecognizer.translationInView(self.centerViewController.view).x+kICSDrawerControllerDrawerDepth } } self.centerViewController.view.frame = c ; break; case UIGestureRecognizerState.Ended: var c = self.centerViewController.view.frame // 表示用户需要展开 if (location.x - self.panGestureStartLocation.x > kICSDrawerControllerLeftViewInitialOffset){ self.didOpen() }else{ if (c.origin.x < (kICSDrawerControllerDrawerDepth - 40)){ self.didClose() }else{ self.didOpen() } } break; default: break; } } // 移除点击事件,添加拖动事件 func tapGestureRecognized(tapGestureRecognizer : UITapGestureRecognizer){ self.didClose(); } // 菜单栏打开 func didOpen(){ var c = self.centerViewController.view.frame c.origin.x = kICSDrawerControllerDrawerDepth; UIView.animateWithDuration(0.7,delay:0,usingSpringWithDamping:0.5,initialSpringVelocity:1.0,options:UIViewAnimationOptions.AllowUserInteraction,animations:{ self.centerViewController.view.frame = c ; },completion: { (finished: Bool) -> Void in }) self.drawerState = ICSDrawerControllerState.MenuControllerStateOpening //增加点击事件 if (self.tapGestureRecognizer == nil){ self.tapGestureRecognizer = UITapGestureRecognizer() self.tapGestureRecognizer.addTarget(self,action:"tapGestureRecognized:"); } self.centerViewController.view.addGestureRecognizer(self.tapGestureRecognizer) } // 菜单关闭 func didClose(){ if (self.drawerState == ICSDrawerControllerState.MenuControllerStateOpening){ self.drawerState = ICSDrawerControllerState.MenuControllerStateClosing self.centerViewController.view.removeGestureRecognizer(self.tapGestureRecognizer) } var c = self.centerViewController.view.frame c.origin.x = 0 UIView.animateWithDuration(0.5,delay:0,usingSpringWithDamping:0.9,initialSpringVelocity:1.0,options:UIViewAnimationOptions.AllowUserInteraction,animations:{ self.centerViewController.view.frame = c ; },completion: { (finished: Bool) -> Void in }) } }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值