IOS 滑动菜单

作者: 半白乀 | 来源:发表于2016-08-27 12:45 被阅读0次

    完整Demo地址
    效果图

    [滑动菜单效果图-github](https://github.com/AllenOoo/SliderMenu-CollectionView)

    结构图

    结构图.png

    Item的属性、状态

    • scaleFloat,Item缩放系数。
    • highlightColor,高亮颜色。
    • 原始状态:scaleFloat = 1,颜色设置的初始颜色
    • 正在放大但不是最大:1 < scaleFloat < Max,颜色为透明度为(scaleFloat/Max)的highlightColor
    • 放大至最大:scaleFloat = Max,颜色 = highlightFloat

    UIScrollView: 为Items提供更多空间
    UIView: 和外部控件联动时控制各Item的状态


    代码

    Item中,只通过一个scaleFloat属性来控制Item的所有状态这样外部使用不容易乱!

    override var scaleFloat: Double {
        didSet {
    
            var scaleColorFloat = scaleFloat;
            var titleColor:UIColor!
            if scaleColorFloat < 1.05 {
                titleColor = UIColor.whiteColor()
            } else {
                if scaleColorFloat < 1.20 {
                    scaleColorFloat = 1.2
                }
    
            titleColor = highlightColor.colorWithAlphaComponent(CGFloat(scaleColorFloat/YZButtonScaleMaxFloat))
            }
            self.setTitleColor(titleColor, forState: .Normal)
            if isNeededAnimation {
                if scaleFloat >= YZButtonScaleMaxFloat {
                    UIView.animateWithDuration(YZButtonTransAnimationInterval, animations: {
                        self.transform = self.transScale(YZButtonScaleMaxFloat)
                    })
                } else {
                    if scaleFloat <= 1.05 {
                        UIView.animateWithDuration(YZButtonTransAnimationInterval, animations: {
                            self.transform = self.transBack()
                        })
                    }
                }
            } else {
                if scaleFloat > YZButtonScaleMaxFloat - 0.05 {
                    self.transform = self.transScale(YZButtonScaleMaxFloat)
                } else {
                    if scaleFloat <= 1.05 {
                        self.transform = self.transBack()
                    } else {
                        self.transform = self.transScale(scaleFloat)
                    }
                }
            }
            isNeededAnimation = false
        }
    }
    

    UIView中的方法

    1. 通过手势滑动距离给当前高亮Item和两边的Item做状态设置
    func itemScaledByDistance(distance: Double) {/// 给对应的item进行缩放
        let scaleFloat = (fabs(distance)/Double(self.frame.width))*YZButtonScaleMaxFloat
        let currentItem = YZButtons[index]
        let nextItem : YZButton?
        if distance > 0 {
            // 左
            if index <= 0 {
                nextItem = YZButton.init(frame: CGRectZero)
            } else {
                nextItem = YZButtons[index-1]
            }
        } else {
            if index >= YZButtons.count-1 {
                nextItem = YZButton.init(frame: CGRectZero)
            } else {
                nextItem = YZButtons[index+1]
            }
        }
        nextItem?.scaleFloat = 1 + scaleFloat
        currentItem?.scaleFloat = YZButtonScaleMaxFloat - scaleFloat
    }
    

    2.手势结束设定对应Item设定最终状态

    func sliderMenuWillScrollToIndex(targetIndex: NSInteger) {
        let lastItem : YZButton?
        let nextItem : YZButton?
        if targetIndex == 0 {
            nextItem = YZButtons[targetIndex + 1]
            lastItem = YZButton.init(frame: CGRectZero)
        } else if targetIndex >= YZButtons.count - 1 {
            nextItem = YZButton.init(frame: CGRectZero)
            lastItem = YZButtons[targetIndex - 1]
        } else {
            nextItem = YZButtons[targetIndex + 1]
            lastItem = YZButtons[targetIndex - 1]
        }
        /// 返回初始状态
        lastItem?.scaleFloat = YZButtonScaleMinFloat
        nextItem?.scaleFloat = YZButtonScaleMinFloat
        index = targetIndex;
    }
    

    CollectionView中需要传给菜单的数据

    1.捕获手势状态

    self.panGestureRecognizer.addTarget(self, action: #selector(panGestureActionInState(_:)))
    
    func panGestureActionInState(gesture: UIPanGestureRecognizer) {
        if gesture.state == .Changed {
            self.gestureDelegate.collectionView(self, panning: gesture)
        }
        if gesture.state == .Ended {
            self.gestureDelegate.collectionView(self, didEndPan: gesture, to: targetIndex)
        }
    }
    

    2.将要停止的目标位置

    func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
        let offsetX = targetContentOffset.memory.x
        targetIndex = lroundf(Float(offsetX/self.frame.width))
    }
    

    最后上下联动

    /// 在菜单中做点击操作
    func didSelectedAtIndex(index: NSInteger, animated: Bool) {
        collection.scrollToItemAtIndexPath(NSIndexPath.init(forRow: index, inSection: 0), atScrollPosition: .CenteredHorizontally, animated: animated)
    }
    /// 滑动CollectionView的过程
    func collectionView(collectionView: SliderMenuInfoView, panning pan: UIPanGestureRecognizer) {
        sliderMenu.itemScaledByDistance(Double(pan.translationInView(collectionView).x))
    }
    /// 手势停止时
    func collectionView(collectionView: SliderMenuInfoView, didEndPan pan: UIPanGestureRecognizer, to targetIndex: NSInteger) {
        sliderMenu.sliderMenuWillScrollToIndex(targetIndex)
    }
    

    完整Demo地址

    相关文章

      网友评论

        本文标题:IOS 滑动菜单

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