【澳门葡京备用网址】页面滑动与题目切换颜色渐变的联动作效果应,斯维夫特斗鱼直播

话不多说,直接上海教室,要实现类似如下效果。

  • 本条职能相当布满,那里首要讲讲基本代码
    澳门葡京备用网址 1

话不多说,直接上海体育场地,要促成类似如下效果。

  • 其1效应卓殊广阔,那里关键讲讲基本代码
    澳门葡京备用网址 2

澳门葡京备用网址 3oc版滚动示例.gif澳门葡京备用网址 4oc版滚动示例二.gif澳门葡京备用网址 5oc版滚动示例三.gif澳门葡京备用网址 6oc版滚动示例4.gif澳门葡京备用网址 7【澳门葡京备用网址】页面滑动与题目切换颜色渐变的联动作效果应,斯维夫特斗鱼直播。oc版滚动示例5.gif澳门葡京备用网址 8oc版滚动示例陆.gif澳门葡京备用网址 9oc版滚动示例七.gif澳门葡京备用网址 10oc版滚动示例捌.gif澳门葡京备用网址 11图片在左手澳门葡京备用网址 12图形在右侧.gif澳门葡京备用网址 13图表在上边.gif澳门葡京备用网址 14只显示图片.gif

效率:首页最下面有二个和显示器等宽的标题栏,点击的时候,可以切换来不相同分界面.类似于TabBarController

封装PageTitleView思路一.自定义View,并且自定义构造函数2.增加子控件

2.一UIScrollView二.2 UILabel — 拿3个数组存放,有序,类型一样2.三UIView — 滚动条二.肆 UIView — 底线

装进顶部的PageTitleView

打包顶部的PageTitleView

企图分为七个部分, 滑块部分View, 内容呈现部分View, 包涵滑块View和呈现内容View的View,以便于能够灵活的应用

  • 一.自定义五个UIView类
  • 2.给该类自定义构造方法,私有属性
    • 留神:重写init构造方法时,无法不重写(无需手写
      ,双击红点,系统活动写上)
      //自定义属性private var titles :
      [String]//自定义构造函数init(frame: CGRect, titles :
      [String]) {self.titles = titlesuper.init(frame:
      frame)}required init?(coder aDecoder: NSCoder) {fatalError(“init
      has not been implemented”)}
  • 三.在首页加多该TitleView
    • 1️⃣增添三个私人住房属性(titleView类型),并且利用懒加载闭包
    • 二️⃣在闭包中对该titleView进行起始化、加多属性,调用该类的自定义构造方法
    • 叁️⃣addSubview到首页中

打包构造函数

  • 包裹构造函数,让别人在成立对象时,就传来其实须求呈现的内容
    • frame:创立对象时规定了frame就足以一向设置子控件的岗位和尺寸
    • isScrollEnable:是否能够滚动。某个地点该控件是足以滚动的。
    • titles:显示的全部标题
  1. // MARK:- 构造函数
  2. init(frame: CGRect, isScrollEnable : Bool, titles : [String]) {
  3. self.isScrollEnable = isScrollEnable
  4. self.titles = titles
  5. super.init(frame: frame)
  6. }

装进构造函数

  • 包装构造函数,让人家在成立对象时,就传来其实需求出示的内容
    • frame:创制对象时规定了frame就足以平昔设置子控件的岗位和尺寸
    • isScrollEnable:是还是不是足以滚动。某个地方该控件是能够滚动的。
    • titles:突显的兼具标题
  1. // MARK:- 构造函数
  2. init(frame: CGRect, isScrollEnable : Bool, titles : [String]) {
  3. self.isScrollEnable = isScrollEnable
  4. self.titles = titles
  5. super.init(frame: frame)
  6. }

一. 滑块部分View

一.壹 要得以落成滑块能够滚动, 思考可以直接使用collectionView,
然而此处依然一向利用scrollView方便里面的控件布局

一.二 要贯彻滑块的点击, 能够向来运用UIButton, 不过因此尝试,
要让button的frame随着文字的大幅来自适应完结比较费心,
所以采用了运用UILabel增添点击手势来落成点击事件,这里运用了closures来得以落成

一.3完毕对应的滚动条和覆盖同步移动的法力,文字颜色渐变作用(在点击的时候一贯运用1个卡通就能够省略的完毕了)

Tips:在付出进度中会用到不少双重参数,比方显示器高宽等……大家得以在Tool文件夹中加多贰个Common.swift文件,专门用来存放公共的多寡参数,经常是常量

设置UI界面

  • 设置UI界面
    • 增添UIScrollView,假使标题过多,则能够滚动
    • 开首化全体的Label,用于体现标题。并且给label增多监听手势
    • 增多顶部线和滑块的View

           达成相对来讲比较轻松,那里代码从略

设置UI界面

  • 设置UI界面
    • 增添UIScrollView,若是标题过多,则能够滚动
    • 开头化全体的Label,用于体现标题。并且给label增加监听手势
    • 增添顶部线和滑块的View

           落成相对来讲相比轻巧,那里代码从略

二. 内容展现部分View

贰.壹 用来作为包括子调控器的view的容器, 并且达成能够分页滚动的职能

2.2 要得以实现分页滚动, 能够运用UIScrollView来促成,
不过这么将要思虑UIScrollView上的各类view的复用的主题材料,
个中细节还是很麻烦, 所以直接行使了UICollectionView来促成

贰.3将每叁个子调节器的view直接加多到对应的每七个cell的contentView中来展现,
所以那里须要专注cell重用大概带来的剧情体现不正规的难点,
那里运用了每便加多contentView的剧情时移除全体的subviews(也足以直接给各样cell用分化的reuseIdentifier完毕)

二.肆达成实时监察和控制滚动的快慢提须求滑块部分来1只调度滚动条和掩盖,文字颜色的渐变,
并且在历次滚动完结的时候能够通告给滑块来调解他的内容

  • 肆.增添子控件
    • UIScrollView
      • 加多1个私人住房属性,然后addSubview到TitleView中
      • 1️⃣懒加载
      • 2️⃣大小与TitleView相同
      • 注意点:必须在调节器View少校自动布局属性设置falseautomaticallyAdjustsScrollViewInsets
        = false
    • UILabel
      • 懒加载增添三个私家属性,专门存放TitleView中逐条label的–数组–
      • 将以下步骤封装在titleView的extension中,并在初叶化titleView时调用
      • 1️⃣ 创建UILabel
      • 2️⃣设置Label属性:text、tag、font、textColor、textAlignment
      • 3️⃣设置Label的frame:for循环中获得index和title,固定label的宽高
      • 四️⃣将label增添到scrollView和民用属性中
    • 澳门葡京备用网址 ,UIView—底线
      • 将以下步骤封装在titleView的extension中,并在开始化titleView时调用
      • 壹️⃣加多底线UIView
      • 2️⃣设置frame
      • 3️⃣添加到titleView
    • UIView—滚动条
      • 将以下步骤封装在titleView的extension中,并在早先化titleView时调用
      • 一️⃣增添滚动条— 产生私有属性,方便调用
      • 2️⃣依照存放label的数组获取第二个label
        • 应用guard因为获取到的是可选类型
      • 叁️⃣依照第一个label设置滚动条的宽高

封装后面部分的PageCotentView

封装尾巴部分的PageCotentView

三. 分包滑块View和呈现内容View的View

三.一 因为滑块部分View和剧情展现部分View是冲突独立的有的,
在这边只要求贯彻两头的通讯就能够

三.二 可以自定义滑块部分View和内容显示部分View的frame

封装ContentView思路一.自定义View,并且自定义构造函数二.增加子控件

2.1UICollectionView—对应layout、datasource2.2
UICollectionViewCell—注册

包裹构造函数

  • 卷入构造函数,让外人在创立对象时,就盛传其实供给出示的剧情
    • 具备用于体以往UICollectionView的Cell的持有调节器
    • 调控器的父调整器
  1. // MARK:- 构造函数
  2. init(frame: CGRect, childVcs : [UIViewController], parentViewController : UIViewController) {
  3. self.childVcs = childVcs
  4. self.parentViewController = parentViewController
  5. super.init(frame: frame)
  6. }

包装构造函数

  • 装进构造函数,让别人在创造对象时,就盛传其实须求浮现的内容
    • 具备用于体以后UICollectionView的Cell的具有调控器
    • 调节器的父调控器
  1. // MARK:- 构造函数
  2. init(frame: CGRect, childVcs : [UIViewController], parentViewController : UIViewController) {
  3. self.childVcs = childVcs
  4. self.parentViewController = parentViewController
  5. super.init(frame: frame)
  6. }

a. 滑块部分

// 滚动条@property (weak, nonatomic) UIView *scrollLine;// 遮盖@property (weak, nonatomic) UIView *coverLayer;// 滚动scrollView@property (weak, nonatomic) UIScrollView *scrollView;// 背景ImageView@property (weak, nonatomic) UIImageView *backgroundImageView;// 附加的按钮@property (weak, nonatomic) UIButton *extraBtn;/// 所有的title设置 -> 使用了一个class ZJSegmentStyle, 将可以自定义的部分全部暴露了出来, 使用的时候就可以比较方便的自定义很多属性 -> 初始化时传入@property (strong, nonatomic) ZJSegmentStyle *segmentStyle;// 所有的标题@property (strong, nonatomic) NSArray *titles;// 用于懒加载计算文字的rgb差值, 用于颜色渐变的时候设置@property (strong, nonatomic) NSArray *deltaRGB;@property (strong, nonatomic) NSArray *selectedColorRgb;@property (strong, nonatomic) NSArray *normalColorRgb;/** 缓存所有标题label */@property (nonatomic, strong) NSMutableArray *titleLabels;// 缓存计算出来的每个标题的宽度@property (nonatomic, strong) NSMutableArray *titleWidths;// 响应标题点击@property (copy, nonatomic) TitleBtnOnClickBlock titleBtnOnClick;

#pragma mark - life cycle- (instancetype)initWithFrame:frame segmentStyle:(ZJSegmentStyle *)segmentStyle titles:(NSArray *)titles titleDidClick:(TitleBtnOnClickBlock)titleDidClick { if (self = [super initWithFrame:frame]) { self.segmentStyle = segmentStyle; self.titles = titles; self.titleBtnOnClick = titleDidClick; _currentIndex = 0; _oldIndex = 0; _currentWidth = frame.size.width; if (!self.segmentStyle.isScrollTitle) { // 不能滚动的时候就不要把缩放和遮盖或者滚动条同时使用, 否则显示效果不好 self.segmentStyle.scaleTitle = !(self.segmentStyle.isShowCover || self.segmentStyle.isShowLine); } // 这个函数里面设置了基本属性中的titles, labelsArray, titlesWidthArray,并且添加了label到scrollView上 [self setupTitles]; // 这个函数里面设置了遮盖, 滚动条,和label的初始化位置 [self setupUI]; } return self;}#pragma mark - button action -> 处理点击title的时候实现标题的切换,和遮盖,滚动条...的位置调整, 同时执行了响应点击的block, 以便于外部相应点击方法- titleLabelOnClick:(UITapGestureRecognizer *)tapGes { ZJCustomLabel *currentLabel = (ZJCustomLabel *)tapGes.view; if (!currentLabel) { return; } _currentIndex = currentLabel.tag; // 同步更改UI [self adjustUIWhenBtnOnClickWithAnimate:true];}- adjustTitleOffSetToCurrentIndex:(NSInteger)currentIndex -> 更改scrollview的contentOffSet来居中显示title // 手动滚动时需要提供动画效果- adjustUIWithProgress:progress oldIndex:(NSInteger)oldIndex currentIndex:(NSInteger)currentIndex -> 提供给外部来执行标题切换之间的动画效果(注意这个方法里面进行了一些简单的数学计算以便于"同步" 滚动滚动条和cell ) 这里以滑块的位置x变化为例, 其他类似 CGFloat xDistance = currentLabel.zj_x - oldLabel.zj_x; 这个xDistance就是滑块将要从一个label下面移动到下一个label下面所需要移动的路程, 这个progress是外界提供来的, 表示当前已经移动的百分比是多少了,所以可以改变当前滑块的x为之前的x + 已经完成滚动的距离(xDistance * progress) scrollLine?.frame.origin.x = oldLabel.frame.origin.x + xDistance * progress 这样就达到了滑块的位置随着提供的progress同步移动 其他的遮盖 和颜色渐变的处理类似

步骤

  • 一.自定义1个UIView类
  • 二.给该类自定义构造函数,定义属性
    • 构造函数中,传入参数:一️⃣数组(存放首页的整整子调控器)2️⃣父调整器;调用设置UI分界面包车型大巴方式
    • 瞩目:构造函数记住要重写系统的required init方法
    • 属性:一️⃣存放子调整器的数组二️⃣父调节器
  • 3.设置UI界面
    • step1:将盛传的子调控器加多到父调整器中
    • step贰:创设collectionView,利用cell的录取机制,复用子调控器view
  • 4.懒加载collectionView
    • step壹:创造布局layout
    • step二:设置collectionView的参数let collectionView =
      UICollectionView(frame: CGRectZero, collectionViewLayout:
      layout)collectionView.showsHorizontalScrollIndicator =
      falsecollectionView.pagingEnabled = truecollectionView.bounces =
      falsecollectionView.dataSource =
      selfcollectionView.registerClass(UICollectionViewCell.self ,
      forCellWithReuseIdentifier: ContentCellID)//获取项目:类名.self
      就能够
    • step三:拓展contentView并贯彻collectionViewDataSource达成其数据源方法
      • 瞩目一:cell必须是挂号的
      • 小心二:cell的contentView由于重用机制会保留原来的view,所以,在赋值前最佳先将原来的view移除!!!防止页面错乱//必须是登记cellfunc
        collectionView(collectionView: UICollectionView,
        cellForItemAtIndex帕特h indexPath: NSIndexPath) ->
        UICollectionViewCell {//壹.创造celllet cell =
        collectionView.dequeueReusableCellWithReuseIdentifier(ContentCellID,
        forIndexPath:
        indexPath)//二.cell设置剧情//防止cell循环利用频仍增进,则把cell原来的先移除再增多新的viefor
        view in
        cell.contentView.subviews{view.removeFromSuperview()}let
        childVc = childVcs[indexPath.item]childVc.view.frame =
        cell.contentView.boundscell.contentView.addSubview(childVc.view)return
        cell}
  • 四.在首页调节器中懒加载contentView属性
    • 运用闭包进行早先化,调用自定义构造函数,传入子调整器数组和父调控器
    • step1:确定cotentView的frame
    • step2:明确cotentView的子调整器,利用for循环成立用数组存放
    • step三:在设置UI方法中addSubview到首页view,并设置颜色

设置UI界面内容

  • 设置UI界面
    • 将具有的子调整器加多到父调整器中
    • 增添UICollectionView,用于体现内容
  1. // MACR-VK:- 懒加载属性
    private lazy var collectionView : UICollectionView = {
    // 1.创建布局
    let layout = UICollectionViewFlowLayout()
    layout.itemSize = self.bounds.size
    layout.minimumLineSpacing = 0
    layout.minimumInteritemSpacing = 0
    layout.scrollDirection = .Horizontal
    // 2.创建collectionView
    let collectionView = UICollectionView(frame: self.bounds, collectionViewLayout: layout)
    collectionView.showsHorizontalScrollIndicator = false
    collectionView.pagingEnabled = true
    collectionView.bounces = false
    collectionView.scrollsToTop = false
    collectionView.dataSource = self
    collectionView.delegate = self
    collectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: kContentCellID)
    return collectionView
    }()
    private func setupUI() {
    // 1.添加所有的控制器
    for childVc in childVcs {
    parentViewController?.addChildViewController(childVc)
    }
    // 2.添加collectionView
    addSubview(collectionView)
    }
    

     

设置UI分界面内容

  • 设置UI界面
    • 将有着的子调节器增加到父调整器中
    • 增多UICollectionView,用于展现内容
  1. // MA大切诺基K:- 懒加载属性
    private lazy var collectionView : UICollectionView = {
    // 1.创建布局
    let layout = UICollectionViewFlowLayout()
    layout.itemSize = self.bounds.size
    layout.minimumLineSpacing = 0
    layout.minimumInteritemSpacing = 0
    layout.scrollDirection = .Horizontal
    // 2.创建collectionView
    let collectionView = UICollectionView(frame: self.bounds, collectionViewLayout: layout)
    collectionView.showsHorizontalScrollIndicator = false
    collectionView.pagingEnabled = true
    collectionView.bounces = false
    collectionView.scrollsToTop = false
    collectionView.dataSource = self
    collectionView.delegate = self
    collectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: kContentCellID)
    return collectionView
    }()
    private func setupUI() {
    // 1.添加所有的控制器
    for childVc in childVcs {
    parentViewController?.addChildViewController(childVc)
    }
    // 2.添加collectionView
    addSubview(collectionView)
    }
    

     

b 内容呈现部分View

// 用于处理重用和内容的显示@property (weak, nonatomic) UICollectionView *collectionView;// collectionView的布局@property (strong, nonatomic) UICollectionViewFlowLayout *collectionViewLayout;/** 避免循环引用*/@property (weak, nonatomic) ZJScrollSegmentView *segmentView;@property (weak, nonatomic) UIButton *extraBtn;// 父类 用于处理添加子控制器 使用weak避免循环引用@property (weak, nonatomic) UIViewController *parentViewController;// 当这个属性设置为YES的时候 就不用处理 scrollView滚动的计算@property (assign, nonatomic) BOOL forbidTouchToAdjustPosition;// 所有的子控制器@property (strong, nonatomic) NSArray *childVcs;

#pragma mark - life cycle - (instancetype)initWithFrame:frame childVcs:(NSArray *)childVcs segmentView:(ZJScrollSegmentView *)segmentView parentViewController:(UIViewController *)parentViewController { if (self = [super initWithFrame:frame]) { self.childVcs = childVcs; self.parentViewController = parentViewController; self.segmentView = segmentView; _oldIndex = 0; _currentIndex = 1; _oldOffSetX = 0.0; self.forbidTouchToAdjustPosition = NO; // 触发懒加载 self.collectionView.backgroundColor = [UIColor whiteColor]; [self commonInit]; } return self;}/** 给外界可以设置ContentOffSet的方法 比如点击了标题的时候需要更改内容显示调用*/- setContentOffSet:offset animated:animated/** 给外界刷新视图的方法 用于动态设置子控制器和标题*/- reloadAllViewsWithNewChildVcs:(NSArray *)newChileVcs { // 这种处理是结束子控制器和父控制器的关系 for (UIViewController *childVc in self.childVcs) { [childVc willMoveToParentViewController:nil]; [childVc.view removeFromSuperview]; [childVc removeFromParentViewController]; }}#pragma mark - UICollectionViewDelegate --- UICollectionViewDataSource- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { return 1;}- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return self.childVcs.count;}- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellID forIndexPath:indexPath]; // 移除subviews 避免重用内容显示错误 [cell.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; // 这里建立子控制器和父控制器的关系 -> 当然在这之前已经将对应的子控制器添加到了父控制器了, 只不过还没有建立完成 UIViewController *vc = (UIViewController *)self.childVcs[indexPath.row]; vc.view.frame = self.bounds; [cell.contentView addSubview:vc.view]; [vc didMoveToParentViewController:self.parentViewController]; return cell;}- scrollViewDidScroll:(UIScrollView *)scrollView -> 这个代理方法中处理了滚动的下标和进度 

贯彻UICollectionView的数据源方法

  • 在回到Cell的方法中,先将cell的contentView中的子控件都移除,幸免循环引用
  • 收取indexPath.item对应的调节器,将调控器的View增加到Cell的contentView中

    // MARK:- 遵守UICollectionView的数据源
    extension PageContentView : UICollectionViewDataSource {
    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return childVcs.count
    }
    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(kContentCellID, forIndexPath: indexPath)
    // 移除之前的
    for subview in cell.contentView.subviews {
    subview.removeFromSuperview()
    }
    // 取出控制器
    let childVc = childVcs[indexPath.item]
    childVc.view.frame = cell.contentView.bounds
    cell.contentView.addSubview(childVc.view)
    return cell
    }
    }
    

     

    PageTitleView点击改换PageContentView

  • 因此代理将PageTitleView的事件传递出去

    /// 定义协议
    protocol PageTitleViewDelegate : class {
    func pageTitleView(pageTitleView : PageTitleView, didSelectedIndex index : Int)
    }
    @objc private func titleLabelClick(tapGes : UITapGestureRecognizer) {
    // 1.获取点击的下标志
    guard let view = tapGes.view else { return }
    let index = view.tag
    // 2.滚到正确的位置
    scrollToIndex(index)
    // 3.通知代理
    delegate?.pageTitleView(self, didSelectedIndex: index)
    }
    

     

    里面调度

    // 内容滚动
    private func scrollToIndex(index : Int) {
    // 1.获取最新的label和之前的label
    let newLabel = titleLabels[index]
    let oldLabel = titleLabels[currentIndex]
    // 2.设置label的颜色
    newLabel.textColor = kSelectTitleColor
    oldLabel.textColor = kNormalTitleColor
    // 3.scrollLine滚到正确的位置
    let scrollLineEndX = scrollLine.frame.width * CGFloat(index)
    UIView.animateWithDuration(0.15) {
    self.scrollLine.frame.origin.x = scrollLineEndX
    }
    // 4.记录index
    currentIndex = index
    }
    

     

  • 在PageContentView中安装当前应当滚动的岗位
  1. // MARK:- 对外暴露方法
  2. extension PageContentView {
  3. func scrollToIndex(index : Int) {
  4. let offset = CGPoint(x: CGFloat(index) * collectionView.bounds.width, y: 0)
  5. collectionView.setContentOffset(offset, animated: false)
  6. }
  7. }

贯彻UICollectionView的数据源方法

  • 在回到Cell的措施中,先将cell的contentView中的子控件都移除,幸免循环引用
  • 抽出indexPath.item对应的调节器,将调整器的View增多到Cell的contentView中

    // MARK:- 遵守UICollectionView的数据源
    extension PageContentView : UICollectionViewDataSource {
    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return childVcs.count
    }
    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(kContentCellID, forIndexPath: indexPath)
    // 移除之前的
    for subview in cell.contentView.subviews {
    subview.removeFromSuperview()
    }
    // 取出控制器
    let childVc = childVcs[indexPath.item]
    childVc.view.frame = cell.contentView.bounds
    cell.contentView.addSubview(childVc.view)
    return cell
    }
    }
    

     

    PageTitleView点击改造PageContentView

  • 透过代理将PageTitleView的风浪传递出去

    /// 定义协议
    protocol PageTitleViewDelegate : class {
    func pageTitleView(pageTitleView : PageTitleView, didSelectedIndex index : Int)
    }
    @objc private func titleLabelClick(tapGes : UITapGestureRecognizer) {
    // 1.获取点击的下标志
    guard let view = tapGes.view else { return }
    let index = view.tag
    // 2.滚到正确的位置
    scrollToIndex(index)
    // 3.通知代理
    delegate?.pageTitleView(self, didSelectedIndex: index)
    }
    

     

    其间调节

    // 内容滚动
    private func scrollToIndex(index : Int) {
    // 1.获取最新的label和之前的label
    let newLabel = titleLabels[index]
    let oldLabel = titleLabels[currentIndex]
    // 2.设置label的颜色
    newLabel.textColor = kSelectTitleColor
    oldLabel.textColor = kNormalTitleColor
    // 3.scrollLine滚到正确的位置
    let scrollLineEndX = scrollLine.frame.width * CGFloat(index)
    UIView.animateWithDuration(0.15) {
    self.scrollLine.frame.origin.x = scrollLineEndX
    }
    // 4.记录index
    currentIndex = index
    }
    

     

  • 在PageContentView中安装当前应当滚动的岗位
  1. // MARK:- 对外暴露方法
  2. extension PageContentView {
  3. func scrollToIndex(index : Int) {
  4. let offset = CGPoint(x: CGFloat(index) * collectionView.bounds.width, y: 0)
  5. collectionView.setContentOffset(offset, animated: false)
  6. }
  7. }

3. “ZJScrollPageView.h”

那1有的是将segmentView和ContentView封装在一同的, 便于使用者间接采纳,
不过你也足以参见那里面包车型地铁兑现, 放肆组合segmentView和ContentView的岗位,
在demo中也有示范

详细请移步OC源码, swift源码,里面都有详尽的德姆o使用示比假设您感觉有支持,无妨给个star鼓励一下, 接待关心

PageContentView滚动调节PageTitleView

通过观察,我们发掘:

                1> 原来职位的Title颜色会日渐变暗

                二>
目标地方的Title颜色会逐步变亮

                3>
变化程度是和滚动的略微有关

因此得出结论:

我们总共必要得到四个值

  • 一> 起初地方下标值
  • 二> 目标地点下标值
  • 三> 当前滚动的进程 

        其实前二点能够由第三点总计而来,可以只供给将进程传递出去。

  • 依据进度值管理标题颜色渐变及滑块逻辑

       
 。当前速度值唯1鲜明了标题的图景,总括出须求发出颜色变化的两相邻标题索引

         。注意:下标值须求幸免越界难点,临界点的处理

贯彻代码

extension PageContentView : UICollectionViewDelegate {

func scrollViewWillBeginDragging(scrollView: UIScrollView) {

startOffsetX = scrollView.contentOffset.x

}

func scrollViewDidScroll(scrollView: UIScrollView) {

// 0.判断是否是点击事件

       if isForbidScrollDelegate { return }

// 1.定义获取需要的数据

        var progress : CGFloat = 0

        let currentOffsetX = scrollView.contentOffset.x

        let scrollViewW = scrollView.bounds.width

             // 1.计算progress

            progress = currentOffsetX / scrollViewW

             // 3.将progress传递给titleView

        delegate?.pageContentView(self, progress: progress)

   }

}

 

 

依靠滚动传入的值,调治PageTitleView

三种颜色必须接纳OdysseyGB值设置(方便通过宝马X5GB实现渐变效果)

private let kNormalRGB : (CGFloat, CGFloat, CGFloat) = (85, 85, 85)

private let kSelectRGB : (CGFloat, CGFloat, CGFloat) = (255, 128, 0)

private let kDeltaRGB = (kSelectRGB.0 - kNormalRGB.0, kSelectRGB.1 - kNormalRGB.1, kSelectRGB.2 - kNormalRGB.2)

private let kNormalTitleColor = UIColor(red: 85/255.0, green: 85/255.0, blue: 85/255.0, alpha: 1.0)

private let kSelectTitleColor = UIColor(red: 255.0/255.0, green: 128/255.0, blue: 0/255.0, alpha: 1.0)

调动scrollLine及多个Label颜色渐变

// MARK:- 对外暴露方法

extension PageTitleView

    func changeLabel(progress: CGFloat) {

//        开启弹簧效果时的过滤处理
        var progress = progress > 0 ? progress : 0

         progress = progress <= CGFloat(titleLabels.count - 1) ? progress : CGFloat(titleLabels.count - 1)

        var leftLabelIndex = Int(floor(progress))

        let ratio = progress - CGFloat(leftLabelIndex)

        //获取leftLabel和rightLabel

        let leftLabel = titleLabels[leftLabelIndex]

        if leftLabelIndex >= 3{

            leftLabelIndex = 3

        }

        print("leftLabelIndex = \(leftLabelIndex)")

        var rightIndex = leftLabelIndex + 1

        if rightIndex >= 3{

            rightIndex = 3

        }

        print("rightIndex = \(rightIndex)")

        let rightLabel = titleLabels[rightIndex]

        //滑块的逻辑

        let moveTotalX = leftLabel.frame.width

        let moveX = moveTotalX * ratio

        scrollLine.frame.origin.x = leftLabel.frame.origin.x + moveX

        //3.Label颜色的渐变

        // 3.1.取出变化的范围

        let colorDelta = (kSelectedColor.0 - kNormalColor.0, kSelectedColor.1 - kNormalColor.1, kSelectedColor.2 - kNormalColor.2)

        if leftLabelIndex != rightIndex {

        // 3.2.变化leftLabel

        leftLabel.textColor = UIColor(r: kSelectedColor.0 - colorDelta.0 * ratio, g: kSelectedColor.1 - colorDelta.1 * ratio, b: kSelectedColor.2 - colorDelta.2 * ratio)

        // 3.2.变化rightLabel

        rightLabel.textColor = UIColor(r: kNormalColor.0 + colorDelta.0 * ratio, g: kNormalColor.1 + colorDelta.1 * ratio, b: kNormalColor.2 + colorDelta.2 * ratio)

        }

        // 4.记录最新的index

        currentIndex = leftLabelIndex
    }
}

 

PageContentView滚动调节PageTitleView

通过观看,我们发掘:

                1> 原来职位的Title颜色会逐步变暗

                二>
目的地点的Title颜色会日趋变亮

                叁>
变化程度是和滚动的有点有关

通过得出结论:

我们总括必要赚取八个值

  • 1> 开头位置下标值
  • 2> 目的地点下标值
  • 三> 当前滚动的快慢 

        其实前二点能够由第二点总计而来,能够只供给将进程传递出去。

  • 遵照进程值管理标题颜色渐变及滑块逻辑

       
 。当前速度值唯1分明了标题的情景,计算出必要发出颜色变化的两相邻题目索引

         。注意:下标值须要防止越界难点,临界点的拍卖

达成代码

extension PageContentView : UICollectionViewDelegate {

func scrollViewWillBeginDragging(scrollView: UIScrollView) {

startOffsetX = scrollView.contentOffset.x

}

func scrollViewDidScroll(scrollView: UIScrollView) {

// 0.判断是否是点击事件

       if isForbidScrollDelegate { return }

// 1.定义获取需要的数据

        var progress : CGFloat = 0

        let currentOffsetX = scrollView.contentOffset.x

        let scrollViewW = scrollView.bounds.width

             // 1.计算progress

            progress = currentOffsetX / scrollViewW

             // 3.将progress传递给titleView

        delegate?.pageContentView(self, progress: progress)

   }

}

 

 

依靠滚动传入的值,调治PageTitleView

二种颜色必须利用KoleosGB值设置(方便通过途乐GB落成渐变效果)

private let kNormalRGB : (CGFloat, CGFloat, CGFloat) = (85, 85, 85)

private let kSelectRGB : (CGFloat, CGFloat, CGFloat) = (255, 128, 0)

private let kDeltaRGB = (kSelectRGB.0 - kNormalRGB.0, kSelectRGB.1 - kNormalRGB.1, kSelectRGB.2 - kNormalRGB.2)

private let kNormalTitleColor = UIColor(red: 85/255.0, green: 85/255.0, blue: 85/255.0, alpha: 1.0)

private let kSelectTitleColor = UIColor(red: 255.0/255.0, green: 128/255.0, blue: 0/255.0, alpha: 1.0)

调动scrollLine及七个Label颜色渐变

// MARK:- 对外暴露方法

extension PageTitleView

    func changeLabel(progress: CGFloat) {

//        开启弹簧效果时的过滤处理
        var progress = progress > 0 ? progress : 0

         progress = progress <= CGFloat(titleLabels.count - 1) ? progress : CGFloat(titleLabels.count - 1)

        var leftLabelIndex = Int(floor(progress))

        let ratio = progress - CGFloat(leftLabelIndex)

        //获取leftLabel和rightLabel

        let leftLabel = titleLabels[leftLabelIndex]

        if leftLabelIndex >= 3{

            leftLabelIndex = 3

        }

        print("leftLabelIndex = \(leftLabelIndex)")

        var rightIndex = leftLabelIndex + 1

        if rightIndex >= 3{

            rightIndex = 3

        }

        print("rightIndex = \(rightIndex)")

        let rightLabel = titleLabels[rightIndex]

        //滑块的逻辑

        let moveTotalX = leftLabel.frame.width

        let moveX = moveTotalX * ratio

        scrollLine.frame.origin.x = leftLabel.frame.origin.x + moveX

        //3.Label颜色的渐变

        // 3.1.取出变化的范围

        let colorDelta = (kSelectedColor.0 - kNormalColor.0, kSelectedColor.1 - kNormalColor.1, kSelectedColor.2 - kNormalColor.2)

        if leftLabelIndex != rightIndex {

        // 3.2.变化leftLabel

        leftLabel.textColor = UIColor(r: kSelectedColor.0 - colorDelta.0 * ratio, g: kSelectedColor.1 - colorDelta.1 * ratio, b: kSelectedColor.2 - colorDelta.2 * ratio)

        // 3.2.变化rightLabel

        rightLabel.textColor = UIColor(r: kNormalColor.0 + colorDelta.0 * ratio, g: kNormalColor.1 + colorDelta.1 * ratio, b: kNormalColor.2 + colorDelta.2 * ratio)

        }

        // 4.记录最新的index

        currentIndex = leftLabelIndex
    }
}

 

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website