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