更新说明: 2016/04/22 增加自定义选中下标功能, 增加 简书个人主页的使用示例
最终效果
一.构思部分:
打算分为三个部分, 滑块部分View, 内容显示部分View, 包含滑块View和显示内容View的View,以便于可以灵活的使用
1. 滑块部分View
1.1 要实现滑块可以滚动, 考虑可以直接使用collectionView, 但是这里还是直接使用scrollView方便里面的控件布局
1.2 要实现滑块的点击, 可以直接使用UIButton, 但是经过尝试, 要让button的frame随着文字的宽度来自适应实现比较麻烦, 所以选择了使用UILabel添加点击手势来实现点击事件,这里使用了closures来实现(可以使用代理模式)
1.3 实现对应的滚动条和遮盖同步移动的效果,文字颜色渐变功能(在点击的时候直接使用一个动画就可以简单的完成了)
2. 内容显示部分View
2.1 用来作为包含子控制器的view的容器, 并且实现可以分页滚动的效果
2.2 要实现分页滚动, 可以使用UIScrollView来实现, 但是这样就要考虑UIScrollView上的各个view的复用的问题, 其中细节还是很麻烦, 所以直接使用了UICollectionView(利用他的重用机制)来实现
2.3 将每一个子控制器的view直接添加到对应的每一个cell的contentView中来展示, 所以这里需要注意cell重用可能带来的内容显示不正常的问题, 这里采用了每次添加contentView的内容时移除所有的subviews(也可以直接给每个cell用不同的reuseIdentifier实现)
2.4 实现实时监控滚动的进度提供给滑块部分来同步调整滚动条和遮盖,文字颜色的渐变, 并且在每次滚动完成的时候可以通知给滑块来调整他的内容
3. 包含滑块View和显示内容View的View
3.1 因为滑块部分View和内容显示部分View是相对独立的部分, 在这里只需要实现两者的通信即可
3.2 可以自定义滑块部分View和内容显示部分View的frame
实现部分
a. 滑块部分
1. 基本属性
/// 所有的title设置 -> 使用了一个结构体, 将可以自定义的部分全部暴露了出来, 使用的时候就可以比较方便的自定义很多属性 -> 初始化时传入的
var segmentStyle: SegmentStyle
/// 点击响应的closures
var titleBtnOnClick:((label: UILabel, index: Int) -> Void)?
/// 用来缓存所有标题的宽度, 达到根据文字的字数和font自适应控件的宽度 -> 为了只计算一次文字的宽度
private var titlesWidthArray: [CGFloat] = []
/// 所有的