ios制作简单侧滑菜单

作者: EgeTart | 来源:发表于2015-08-13 11:18 被阅读9413次

    说明:在Xcode7 beta5 中制作完成

    1. 创建一个Single View Application,填写相应信息,选择一个目录存储工程。


    2. 打开Main.storyboard,取消勾选Use Size Class,完成后设计视图的大小将会呈现iphone大小


    3. 在storyboard中选中View Controller,单击菜单栏上的Editor菜单,依次选择Embed In和Navigation Controller。



      完成后如下所示


    4. 选中Navigation Bar,改变它的Bar Tint(可以省略不做)



      完成后的效果图


    5. 导入要使用到的资源文件
      单击Assets.xcassets文件夹,把要使用到的菜单图标拖放到图片资源框中。



      完成后


    6. 拖放一个Bar Button Item到Navigation Bar上, 设置它的image属性。



      完成后的效果图
    7. 从控件库中拖一个TableView到View Controller中,选中TableView,把它的Prototype Cells的数量设置为1,接着改变TableView的位置和大小。


    8. 展开TableView选中TableViewCell,设置它的identifier以及它的高度


    9. 再次选中TableView,给它增加约束。单击右下角的第3个按钮,给TableView增加如下约束(上边距和左边距为0)。这里把高度设置为544和宽度设置为80的原因是,每个菜单的大小为(80 x 80),导航栏的高度为64,一共有6个菜单,所以高度为544,宽度为80.


    10. 从控件库中拖一个ImageView到TableViewCell中,改变它的位置大小。



      给ImageView添加约束并给它设置一个tag


    11. 打开辅助视图,会呈现storyboard和代码编辑区


    12. 选中TableView按住ctrl键,鼠标左键拖拽一个outlet到ViewController代码文件中。


    接下来添加代码,一步一步实现侧滑菜单的功能

    在viewDidLoad()方法上添加一个数组,用来存储菜单图标的名字。
    let menuIcons = ["dribble-flat", "evernote-flat", "facebook-flat", "google-plus-flat", "pandora-flat", "phone-flat"]
    让ViewController遵循UITableView的两个协议
    class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
    此时编译器会报错,因为还没有实现必须的代理方法。现在实现必须的代理方法。

    //设置TableViewCell的高度
    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
           return 80 
    }
    
      //  设置TableView的行数
        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
           return menuIcons.count
        }
    
    // 配置每个TableViewCell 
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
            // 1. 获取到可重用的cell
         let cell = tableView.dequeueReusableCellWithIdentifier("menuCell") as UITableViewCell!
            
            // 2. 拿到imageView
            let menuImageView = cell.viewWithTag(715) as! UIImageView
            
            // 3. 设置imageView的图片
            menuImageView.image = UIImage(named: menuIcons[indexPath.row])
            return cell
    }
    

    到此时为止,代码文件看起来应该类似这样。

    import UIKit
    //3. 遵循TableView的两个协议
    class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
     // 1. 拖拽生成tableview的outlet
        @IBOutlet weak var menuTableView: UITableView!
        
        // 2.菜单图标名数组
        let menuIcons = ["dribble-flat", "evernote-flat", "facebook-flat", "google-plus-flat", "pandora-flat", "phone-flat"]
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
        }
        
        // 4. 实现代理方法
        // 设置TableViewCell的高度
        func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
            return 80
        }
        
        // 设置TableView的行数
        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return menuIcons.count
        }
        
        // 配置每个TableViewCell
      func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
            // 1. 获取到可重用的cell
            let cell = tableView.dequeueReusableCellWithIdentifier("menuCell") as UITableViewCell!
            
            // 2. 拿到imageView
            let menuImageView = cell.viewWithTag(715) as! UIImageView
            
            // 3. 设置imageView的图片
            menuImageView.image = UIImage(named: menuIcons[indexPath.row])
            
            return cell
           }
    }
    

    运行一下,看有什么效果



    哇!只有一个空的列表。为什么会这样呢??因为还没有指定TableView的代理人是谁,那么TableView的代理就没有人在执行。现在给TableView指定代理人,在viewDidLoad()方法中添加两行代码。

     menuTableView.dataSource = self
     menuTableView.delegate = self
    

    这两行代码的作用是,把menuTableView的代理人指定为当前的ViewController,那么当前的ViewController就会执行TableView的代理方法,为menuTableView提供数据以及对menuTableView的行为负责。
    OK,再次运行,看下效果



    还不错,菜单图标已经显示出来了!!
    接下来,先用触发按钮来控制菜单的出现与隐藏...
    首先在viewDidLoad()方法的下方添加以下代码,把菜单隐藏掉,这样程序启动完成后,就不会把菜单显示出来

    override func viewDidAppear(animated: Bool) {
            super.viewDidAppear(animated)
            
            // 获取到所有显示的cell
            let cells = menuTableView.visibleCells
            
            // 把cell移动至可视区域外
            for cell in cells {
                cell.frame.origin = CGPoint(x: -80, y: cell.frame.origin.y)
            }
        }
    

    在viewDidLoad()方法的上方添加一个菜单的状态标记,用来记录菜单的显示状态

    //一开始菜单的状态为隐藏
    var isShow = false
    

    在最后一个花括号的上方,添加一个辅助函数,用来更改菜单的位置和状态,达到显示和隐藏的效果

    func menuStateChange() {
            
            let cells = menuTableView.visibleCells
            //如果当前菜单的状态为隐藏,则让每个菜单显示出来
            if isShow == false {
    
                //改变每个cell的原点位置
                for cell in cells {
                    cell.frame.origin = CGPoint(x: 0, y: cell.frame.origin.y)
                }
                
            }
            else {
                for cell in cells {
                    cell.frame.origin = CGPoint(x: -80, y: cell.frame.origin.y)
                }
            }
            //改变菜单的显示状态
            isShow = !isShow
        }
    

    接着在menuStateChange()的下方添加一个Action,这个Action将由导航栏上的按钮触发

    //  触发或关闭菜单
    @IBAction func trigger(sender: AnyObject) {
            menuStateChange()
        }
    

    回到Storyboard中,让按钮关联这个Action. 选中Bar Button Item,按住ctrl键,鼠标左键拖拽至View Controller,在弹出菜单中选择trigger:



    现在运行一下程序,可以发现用按钮控制菜单显示状态的目标完成啦。。。
    接下来用手指的滑动来控制菜单的显示状态
    First. 在代码文件中添加用手机滑动屏幕时会执行的Action

    // 实现滑动手势,判断滑动方向是否与当前菜单状态吻合
        @IBAction func swipe(gesture: UISwipeGestureRecognizer) {
            
            // 往左滑关掉菜单
            if gesture.direction == UISwipeGestureRecognizerDirection.Left && isShow == true {
                menuStateChange()
            }
            else if gesture.direction == UISwipeGestureRecognizerDirection.Right && isShow == false {
                menuStateChange()
            }
    }
    

    ok, 回到storyboard,增加两个滑动手势识别器.从控件库中拖放一个Swipe Gesture Recognizer到View Controller中,让View Controller的view能够识别到滑动手势.



    选中Swipe Gesture Recognizer,按住ctrl键,鼠标左键拖拽至View Controller,在弹出菜单中选择swipe:,让手势识别器关联到要执行的Action



    运用相同的方法,再拖一个Swipe Gesture Recognizer到View Controller中,此时有一个地方要修改,因为滑动手势识别器的识别方向默认为向右滑. 选中刚添加的手势,修改它的识别方向. 同时将它与swipe Action关联。

    运行程序,看下效果. 左右滑动可以控制菜单的显示状态,按钮也工作正常,两者没有冲突。
    为了让菜单的隐藏与出现具有动态效果,现在给每一个菜单加一个动画.
    修改menuStateChange()函数,添加动画效果.

        func menuStateChange() {
            
            let cells = menuTableView.visibleCells
            //一个单位的延迟时间
            let diff = 0.05
            
            if isShow == false {
                
                for cell in cells {
                    cell.frame.origin = CGPoint(x: -80, y: cell.frame.origin.y)
                }
                
                // 给每个cell增加动画
                for i in 0..<cells.count {
                    
                    let cell = cells[i]
                    
                   //动画效果
                    UIView.animateWithDuration(0.3, delay: Double(i+1) * diff,
                        options: UIViewAnimationOptions.CurveEaseIn,
                        animations: { () -> Void in
                        cell.frame.origin = CGPoint(x: 0, y: cell.frame.origin.y)
                        },
                        completion: nil)
                }
                
            }
            else {
    
                for i in (0..<cells.count).reverse() {
                    let cell = cells[i]
                    UIView.animateWithDuration(0.3, delay: Double(6 - i) * diff,
                        options: UIViewAnimationOptions.CurveEaseIn,
                        animations: { () -> Void in
                        cell.frame.origin = CGPoint(x: -80, y: cell.frame.origin.y)
                        },
                        completion: nil)
                }
            }
            
            isShow = !isShow
        }
    

    解释一下实现动画效果的代码

     UIView.animateWithDuration(0.3, delay: Double(i+1) * diff,
                        options: UIViewAnimationOptions.CurveEaseIn,
                        animations: { () -> Void in
                        cell.frame.origin = CGPoint(x: 0, y: cell.frame.origin.y)
                        },
                        completion: nil)
    

    第一个参数是每个Cell执行动画的时间,为0.3秒
    第二个参数是动画的延迟时间,因为希望菜单一个接一个的出现,所以每个菜单都会比上一个菜单有一个单位时间的延迟
    第三个参数是动画按指定速率变化曲线执行,这里的速率变化曲线为CurveEaseIn
    第四个参数是要实现的动画效果,这里改变每个cell的原点位置,控制它的显示状态
    第五个参数是动画结束后要执行的事情,这里为nil,表明什么都不做.

    ok,侧滑菜单制作完了,运行看下效果吧!!

    出现时的效果


    相关文章

      网友评论

        本文标题:ios制作简单侧滑菜单

        本文链接:https://www.haomeiwen.com/subject/lggiqttx.html