美文网首页iOS
【iOS】一种简易侧边栏的实现

【iOS】一种简易侧边栏的实现

作者: 刘大帅 | 来源:发表于2015-11-06 16:09 被阅读6394次

    参考文章

    SlideMenuControllerSwift

    实现原理

    本文几乎以最简化的方式来实现一种侧边栏效果,方便理解其原理,所以,只有tap手势过渡效果,并未实现pan的侧滑效果.

    实现这种效果,要用容器控制器的概念.通过容器控制器中不同容器视图的切换,来实现.

    实现的难点在于容器视图切换中,动画效果平缓自然.

    SlideMenuDemo.gif

    容器视图切换的核心代码:

        func setUpViewController(targetView: UIView, targetViewController: UIViewController?) {
            
            if let viewController = targetViewController {
                
                addChildViewController(viewController)
                
                viewController.view.frame = targetView.bounds
                
                targetView.addSubview(viewController.view)
                
                viewController.didMoveToParentViewController(self)
                
            }
        }
        
        func removeViewController(viewController: UIViewController?) {
            
            if let _viewController = viewController {
                
                _viewController.willMoveToParentViewController(nil)
                _viewController.view.removeFromSuperview()
                _viewController.removeFromParentViewController()
            }
        }  
    

    过渡动画的核心代码:

        override func openLeft() {
        
            leftVC?.beginAppearanceTransition(isLeftHidden(), animated: true)
            openLeftWithVelocity(0)
        }
        
        func openLeftWithVelocity(velocity: CGFloat) {
        
            let xOrigin: CGFloat = leftContainerView.frame.origin.x
            let finalXOrigin: CGFloat = 0
            
            var frame: CGRect = leftContainerView.frame
            
            frame.origin.x = finalXOrigin
            
            var duration: NSTimeInterval = Double(SlideMenuOptions.animationDuration)
            
            if velocity != 0 {
            
                duration = Double(fabs(xOrigin - finalXOrigin)/velocity)
                
                duration = Double(fmax(0.1, fmin(1, duration)))
            }
            
            UIView.animateWithDuration(duration, delay: 0, options: UIViewAnimationOptions.CurveEaseIn, animations: { [weak self]() -> Void in
                
                if let strongSelf = self {
                
                    strongSelf.leftContainerView.frame = frame
    
                    strongSelf.mainContainerView.transform = CGAffineTransformMakeScale(SlideMenuOptions.contentViewScale, SlideMenuOptions.contentViewScale)
                }
                
                }) { [weak self](Bool) -> Void in
                    
                    if let strongSelf = self {
                    
                        strongSelf.leftVC?.endAppearanceTransition()
                    }
            }
        }
        
        override func closeLeft() {
        
            leftVC?.beginAppearanceTransition(isLeftHidden(), animated: true)
            closeLeftWithVelocity(0)
        }
        
        func closeLeftWithVelocity(velocity: CGFloat) {
        
            let xOrigin: CGFloat = leftContainerView.frame.origin.x
            let finalXOrigin: CGFloat = leftMinOrigin()
            
            var frame: CGRect = leftContainerView.frame
            frame.origin.x = finalXOrigin
            
            var duration: NSTimeInterval = Double(SlideMenuOptions.animationDuration)
            
            if velocity != 0 {
            
                duration = Double(fabs(xOrigin - finalXOrigin)/velocity)
                
                duration = Double(fmax(0.1, fmin(1, duration)))
            }
            
            UIView.animateWithDuration(duration, delay: 0, options: UIViewAnimationOptions.CurveEaseIn, animations: { [weak self]() -> Void in
                
                if let strongSelf = self {
                
                    strongSelf.leftContainerView.frame = frame
                    strongSelf.mainContainerView.transform = CGAffineTransformMakeScale(1, 1)
                }
                
                }) { [weak self](Bool) -> Void in
                    
                    if let strongSelf = self {
                        
                        strongSelf.leftVC?.endAppearanceTransition()
                    }
                    
            }
        }
        
        func isPointContainedWithinLeftRect(point: CGPoint) -> Bool {
            
            return CGRectContainsPoint(leftContainerView.frame, point)
        }  
    

    下载源码

    下载地址

    相关文章

      网友评论

        本文标题:【iOS】一种简易侧边栏的实现

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