PageTitleView:

#import <UIKit/UIKit.h>

@class GFBPageTitleView;
@protocol GFBPageTitleViewDelegate <NSObject> - (void)pageTitleView:(GFBPageTitleView *)pageTitleView selectedIndex:(int)index; @end @interface GFBPageTitleView : UIView - (instancetype)initWithFrame:(CGRect)frame titles:(NSArray *)titlesArray;
@property (nonatomic,weak)id<GFBPageTitleViewDelegate> delegate; - (void)setTitleWithProgress:(CGFloat)progress soureceIndex:(int)sourceIndex targetIndex:(int)targetIndex; @end
//
// GFBPageTitleView.m
// elmsc
//
// Created by MAC on 2016/11/26.
// Copyright © 2016年 GFB Network Technology Co.,Ltd. All rights reserved.
// #import "GFBPageTitleView.h" // 线条的高度
#define kScrollLineH 2.0 @interface GFBPageTitleView () @property (nonatomic, strong) NSArray *titlesArray;
@property (nonatomic, strong) NSMutableArray *titlesLabelArray; @property (nonatomic, strong) UIScrollView *contentScrollView;
@property (nonatomic, strong) UIView *scrollLineView;
@property (nonatomic, assign) NSInteger currentIndex; @end @implementation GFBPageTitleView #pragma mark--懒加载
- (UIScrollView *)contentScrollView
{
if (! _contentScrollView) {
_contentScrollView = [[UIScrollView alloc]init];
_contentScrollView.showsHorizontalScrollIndicator = NO;
_contentScrollView.scrollsToTop = NO;
_contentScrollView.bounces = NO;
}
return _contentScrollView;
} - (UIView *)scrollLineView
{
if (! _scrollLineView) {
_scrollLineView = [[UIView alloc]init];
_scrollLineView.backgroundColor = [UIColor orangeColor];
}
return _scrollLineView;
} - (instancetype)initWithFrame:(CGRect)frame titles:(NSArray *)titlesArray
{
self = [super initWithFrame:frame];
if (self) { self.titlesArray = titlesArray;
[self setUpUI];
return self;
}
return nil;
} #pragma mark--Private Methods 自定义方法
- (void) setUpUI
{
self.titlesLabelArray = [NSMutableArray array];
// 添加滚动视图
[self addSubview:self.contentScrollView];
self.contentScrollView.frame = self.bounds; // 添加title对应的Label
[self setUpTitleLabels]; // 设置底线和滚动的滑块
[self setupBottomLineAndScrollLine]; } - (void) setUpTitleLabels
{
// 0.确定label的一些frame的值
CGFloat labelW = self.frame.size.width / (CGFloat)(self.titlesArray.count);
CGFloat labelH = self.frame.size.height - kScrollLineH;
CGFloat labelY = ; [self.titlesArray enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { UILabel *label = [[UILabel alloc]init];
label.text = obj;
label.tag = idx;
label.font = [UIFont systemFontOfSize:];
label.textColor = [UIColor lightGrayColor];
label.textAlignment = NSTextAlignmentCenter; CGFloat labelX = labelW * (CGFloat)(idx);
label.frame = CGRectMake(labelX, labelY, labelW, labelH);
[self.contentScrollView addSubview:label];
[self.titlesLabelArray addObject:label]; // 添加到数组中 // 添加手势点击
label.userInteractionEnabled = YES; // 允许交互
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(titleLabelClick:)];
[label addGestureRecognizer:tap]; }]; } - (void) setupBottomLineAndScrollLine
{ // 1.添加底线(底部的线暂时不需要)
UIView *bottomLine = [UIView new];
bottomLine.backgroundColor = [UIColor lightGrayColor];
CGFloat lineH = 0.5;
bottomLine.frame = CGRectMake(, self.frame.size.height - lineH, self.frame.size.width, lineH);
//[self addSubview:bottomLine]; // 2.添加scrollLine
// 2.1.获取第一个Label
UILabel *firstLabel = self.titlesLabelArray.firstObject;
firstLabel.textColor = [UIColor lightGrayColor]; // 2.2.设置scrollLine的属性
[self.contentScrollView addSubview:self.scrollLineView];
self.scrollLineView.frame = CGRectMake(firstLabel.frame.origin.x, self.frame.size.height - kScrollLineH, firstLabel.frame.size.width, kScrollLineH);
} #pragma mark--Action 点击方法
- (void) titleLabelClick:(UITapGestureRecognizer *)tapGes
{
// 0.获取当前Label
UILabel *currentLabel = (UILabel *)tapGes.view;
// 1.如果是重复点击同一个Title,那么直接返回
if (currentLabel.tag == self.currentIndex) { return; } // 2.获取之前的Label
UILabel *oldLabel = self.titlesLabelArray[_currentIndex]; // 3.切换文字的颜色
currentLabel.textColor = [UIColor lightGrayColor];
//UIColor(r: kSelectColor.0, g: kSelectColor.1, b: kSelectColor.2)
oldLabel.textColor = [UIColor lightGrayColor];
//UIColor(r: kNormalColor.0, g: kNormalColor.1, b: kNormalColor.2) // 4.保存最新Label的下标值
self.currentIndex = currentLabel.tag; // 5.滚动条位置发生改变
CGFloat scrollLineX = (CGFloat)(_currentIndex) * self.scrollLineView.frame.size.width;
[UIView animateWithDuration:0.15 animations:^{
CGRect rect = self.scrollLineView.frame;
rect.origin.x = scrollLineX;
self.scrollLineView.frame = rect; }]; // 通知代理
[self.delegate pageTitleView:self selectedIndex:(int)self.currentIndex]; } #pragma mark--对外的方法
- (void)setTitleWithProgress:(CGFloat)progress soureceIndex:(int)sourceIndex targetIndex:(int)targetIndex
{
// 1.取出sourceLabel/targetLabel
UILabel *sourceLabel = self.titlesLabelArray[sourceIndex];
UILabel *targetLabel = self.titlesLabelArray[targetIndex]; // 2.处理滑块的逻辑
CGFloat moveTotalX = targetLabel.frame.origin.x - sourceLabel.frame.origin.x;
CGFloat moveX = moveTotalX * progress;
CGRect rect = self.scrollLineView.frame;
rect.origin.x = sourceLabel.frame.origin.x + moveX;
self.scrollLineView.frame = rect; // 3.颜色的渐变(复杂)
// 3.1.取出变化的范围
// let colorDelta = (kSelectColor.0 - kNormalColor.0, kSelectColor.1 - kNormalColor.1, kSelectColor.2 - kNormalColor.2) // 3.2.变化sourceLabel
sourceLabel.textColor = [UIColor lightGrayColor];
//UIColor(r: kSelectColor.0 - colorDelta.0 * progress, g: kSelectColor.1 - colorDelta.1 * progress, b: kSelectColor.2 - colorDelta.2 * progress) // 3.2.变化targetLabel
targetLabel.textColor = [UIColor lightGrayColor];
//UIColor(r: kNormalColor.0 + colorDelta.0 * progress, g: kNormalColor.1 + colorDelta.1 * progress, b: kNormalColor.2 + colorDelta.2 * progress) // 4.记录最新的index
self.currentIndex = targetIndex;
} @end

PageContentView:

//
// GFBPageContentView.h
// elmsc
//
// Created by MAC on 2016/11/26.
// Copyright © 2016年 GFB Network Technology Co.,Ltd. All rights reserved.
// #import <UIKit/UIKit.h> @class GFBPageContentView;
@protocol GFBPageContentViewDelegate <NSObject> - (void)pageContentView:(GFBPageContentView *)view
progress:(CGFloat)progress
sourceIndex:(int)sourceIndex
targetIndex:(int)targetIndex; @end @interface GFBPageContentView : UIView
// 重写方法
- (instancetype)initWithFrame:(CGRect)frame childVcs:(NSMutableArray *) vcArray parentViewController:(UIViewController *) controller; // 对外的暴露方法
-(void)setCurrentIndex:(int)currentIndex; @property (nonatomic, weak)id<GFBPageContentViewDelegate> delegate;
@end
//
// GFBPageContentView.m
// elmsc
//
// Created by MAC on 2016/11/26.
// Copyright © 2016年 GFB Network Technology Co.,Ltd. All rights reserved.
// #import "GFBPageContentView.h" static NSString *ContentCellID = @"ContentCellID";
@interface GFBPageContentView ()<UICollectionViewDataSource,UICollectionViewDelegate,UIScrollViewDelegate> @property (nonatomic, strong) UICollectionView *contentCollectView;
@property (nonatomic, strong) NSMutableArray *childVcArray;
@property (nonatomic, weak) UIViewController *parentViewController; @property (nonatomic, assign) CGFloat startOffsetX;
@property (nonatomic, assign) BOOL isForbidScrollDelegate; @end
@implementation GFBPageContentView #pragma mark--懒加载
- (UICollectionView *) contentCollectView
{
if (! _contentCollectView) {
// 创建布局
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init];
layout.itemSize = self.bounds.size;
layout.minimumInteritemSpacing = ;
layout.minimumLineSpacing = ;
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal; // 2.创建UICollectionView
_contentCollectView = [[UICollectionView alloc]initWithFrame:CGRectZero collectionViewLayout:layout];
_contentCollectView.showsHorizontalScrollIndicator = NO;
_contentCollectView.pagingEnabled = YES;
_contentCollectView.bounces = NO;
_contentCollectView.dataSource = self;
_contentCollectView.delegate = self;
_contentCollectView.scrollsToTop = NO;
_contentCollectView.backgroundColor = [UIColor whiteColor]; [_contentCollectView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:ContentCellID]; }
return _contentCollectView;
} #pragma mark--Systems Methods 系统方法
- (instancetype)initWithFrame:(CGRect)frame childVcs:(NSMutableArray *) vcArray parentViewController:(UIViewController *) controller
{
self = [super initWithFrame:frame];
if (self) { self.childVcArray = vcArray;
self.parentViewController = controller;
[self setUpUI];
return self;
}
return nil;
} #pragma mark--Private Methods 自定义方法 私有
- (void) setUpUI{ self.startOffsetX = ;
self.isForbidScrollDelegate = NO; for (UIViewController *vc in self.childVcArray) {
[self.parentViewController addChildViewController:vc];
}
[self addSubview:self.contentCollectView];
self.contentCollectView.frame = self.bounds;
} #pragma mark--对外的暴露方法
// 对外的暴露方法
-(void)setCurrentIndex:(int)currentIndex
{
// 1.记录需要进制执行代理方法
self.isForbidScrollDelegate = YES; // 2.滚动正确的位置
CGFloat offsetX = (CGFloat)(currentIndex) * self.contentCollectView.frame.size.width;
[self.contentCollectView setContentOffset:CGPointMake(offsetX, ) animated:NO];
} #pragma mark-UICollectionView Methods 数据源方法
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return self.childVcArray.count;
} - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ContentCellID forIndexPath:indexPath];
// 给cell设置内容
for (id view in cell.contentView.subviews) {
[view removeFromSuperview];
} UIViewController *vc = self.childVcArray[indexPath.item];
vc.view.frame = cell.contentView.bounds;
[cell.contentView addSubview:vc.view]; return cell;
} #pragma mark - UIScrollerViewDelegate Methods 代理方法
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
self.isForbidScrollDelegate = NO;
self.startOffsetX = scrollView.contentOffset.x;
} - (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
// 0.判断是否是点击事件
if (self.isForbidScrollDelegate) {
return;
} // 1.定义需要的数据
CGFloat progress = ;
int sourceIndex = ;
int targetIndex = ; // 2.判断是左滑还是右滑
CGFloat currentOffsetX = scrollView.contentOffset.x;
CGFloat scrollViewW = scrollView.bounds.size.width;
if (currentOffsetX > self.startOffsetX) { // 左滑 // 1.计算progress
progress = currentOffsetX / scrollViewW - floor(currentOffsetX / scrollViewW); // 2.计算sourceIndex
sourceIndex = (int)(currentOffsetX / scrollViewW); // 3.计算targetIndex
targetIndex = sourceIndex + ;
if (targetIndex >= self.childVcArray.count) {
targetIndex = (int)self.childVcArray.count - ;
} // 4.如果完全划过去
if (currentOffsetX - self.startOffsetX == scrollViewW) {
progress = ;
targetIndex = sourceIndex;
}
}else{ // 右滑 // 1.计算progress
progress = - (currentOffsetX / scrollViewW - floor(currentOffsetX / scrollViewW)); // 2.计算targetIndex
targetIndex = (int)(currentOffsetX / scrollViewW); // 3.计算sourceIndex
sourceIndex = targetIndex + ;
if (sourceIndex >= self.childVcArray.count) {
sourceIndex = (int)self.childVcArray.count - ;
}
} [self.delegate pageContentView:self progress:progress sourceIndex:sourceIndex targetIndex:targetIndex]; } @end

使用:

//
// GFBTypeGoodsDetailViewController.m
// elmsc
//
// Created by MAC on 2016/11/26.
// Copyright © 2016年 GFB Network Technology Co.,Ltd. All rights reserved.
// #import "GFBTypeGoodsDetailViewController.h"
#import "GFBPageTitleView.h"
#import "GFBPageContentView.h"
#import "GFBCommentViewController.h"
#import "GFBProductViewController.h"
#import "GFBProuctDetailViewController.h" @interface GFBTypeGoodsDetailViewController ()<GFBPageTitleViewDelegate,GFBPageContentViewDelegate> @property (nonatomic, strong) GFBPageTitleView *pageTitleView;
@property (nonatomic, strong) GFBPageContentView *pageContentView; @end @implementation GFBTypeGoodsDetailViewController #pragma mark--懒加载
- (GFBPageTitleView *)pageTitleView
{
if (! _pageTitleView) {
NSMutableArray *arry = [NSMutableArray arrayWithObjects:@"产品",@"详情",@"评价", nil];
_pageTitleView = [[GFBPageTitleView alloc]initWithFrame:CGRectMake(, , * frameW / 375.0, ) titles:arry];
_pageTitleView.delegate = self;
}
return _pageTitleView;
} - (GFBPageContentView *)pageContentView
{
if (! _pageContentView) {
NSMutableArray *vcArray = [NSMutableArray array];
// 产品
GFBProductViewController *productVc = [GFBProductViewController new];
// 详情
GFBProuctDetailViewController *productDetailVc = [GFBProuctDetailViewController new];
// 评论
GFBCommentViewController *commentVc = [GFBCommentViewController new];
[vcArray addObject:productVc];
[vcArray addObject:productDetailVc];
[vcArray addObject:commentVc]; _pageContentView = [[GFBPageContentView alloc]initWithFrame:CGRectMake(, , frameW, frameH - ) childVcs:vcArray parentViewController:self];
//NSLog(@"当前的高度%f",self.view.bounds.size.height);
_pageContentView.delegate = self; }
return _pageContentView;
} - (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.title = @"商品详情";
} - (void)viewDidLoad {
[super viewDidLoad];
[self setUpUI];
} #pragma mark-Private Methods 自定义方法
- (void) setUpUI
{
[self setUpNavBar];
[self setUpContentView];
} - (void) setUpNavBar
{
self.navigationItem.titleView = self.pageTitleView;
} - (void) setUpContentView
{
[self.view addSubview:self.pageContentView];
} #pragma mark-GFBPageTitleViewDelegate Method
- (void)pageTitleView:(GFBPageTitleView *)pageTitleView selectedIndex:(int)index
{
[self.pageContentView setCurrentIndex:index];
} #pragma mark-GFBPageContentViewDelegate Method
- (void)pageContentView:(GFBPageContentView *)view progress:(CGFloat)progress sourceIndex:(int)sourceIndex targetIndex:(int)targetIndex
{
[self.pageTitleView setTitleWithProgress:progress soureceIndex:sourceIndex targetIndex:targetIndex];
} @end

第十四篇、OC_新闻查看器的更多相关文章

  1. 第十四篇 Integration Services:项目转换

    本篇文章是Integration Services系列的第十四篇,详细内容请参考原文. 简介在前一篇,我们查看了SSIS变量,变量配置和表达式管理动态值.在这一篇,我们使用SQL Server数据商业 ...

  2. 【译】第十四篇 Integration Services:项目转换

    本篇文章是Integration Services系列的第十四篇,详细内容请参考原文. 简介在前一篇,我们查看了SSIS变量,变量配置和表达式管理动态值.在这一篇,我们使用SQL Server数据商业 ...

  3. 解剖SQLSERVER 第十四篇 Vardecimals 存储格式揭秘(译)

    解剖SQLSERVER 第十四篇    Vardecimals 存储格式揭秘(译) http://improve.dk/how-are-vardecimals-stored/ 在这篇文章,我将深入研究 ...

  4. Egret入门学习日记 --- 第十四篇(书中 5.4~5.6节 内容)

    第十四篇(书中 5.4~5.6节 内容) 书中内容: 总结 5.4节 内容重点: 1.如何编写自定义组件? 跟着做: 重点1:如何编写自定义组件? 文中提到了重要的两点. 好,我们来试试看. 第一步, ...

  5. Spring Cloud第十四篇 | Api网关Zuul

    ​ 本文是Spring Cloud专栏的第十四篇文章,了解前十三篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring C ...

  6. Python之路【第十四篇】:AngularJS --暂无内容-待更新

    Python之路[第十四篇]:AngularJS --暂无内容-待更新

  7. 跟我学SpringCloud | 第十四篇:Spring Cloud Gateway高级应用

    SpringCloud系列教程 | 第十四篇:Spring Cloud Gateway高级应用 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 ...

  8. SpringBoot第二十四篇:应用监控之Admin

    作者:追梦1819 原文:https://www.cnblogs.com/yanfei1819/p/11457867.html 版权声明:本文为博主原创文章,转载请附上博文链接! 引言   前一章(S ...

  9. Hibernate(十四篇)

    (一)Hibernate简介 (二)hibernate配置管理 (三)Hibernate对象-关系映射文件 (四)Hibernate API详解 (五)Hibernate一级缓存 (六)Hiberna ...

随机推荐

  1. Spring学习(二)Spring的bean管理(XML)

    Bean的实例化方式 1.在Spring里面通过配置文件创建对象 2.bean实例化的三种方式第一种:使用类的无参数构造函数创建(最常用的方式,第2种和第3种方法一般不用) 如果类里面没有无参的构造函 ...

  2. SSRF总结

    ssrf漏洞,全称为服务端请求伪造漏洞,由于有的web应用需要实现从其它服务器上获取资源的功能,但是没有对url进行限制,导致可以构造非本意的url对内网或者其它服务器发起恶意请求.ssrf漏洞的危害 ...

  3. linux安装jdk7步骤

    linux安装jdk7步骤: 1.首先使用命令查看linux系统版本号: lsb_release -a 2.下载对应的jdk版本,笔者使用的是jdk-7u79-linux-x64.tar.gz: 3. ...

  4. iOS书摘之Objective-C编程之道 iOS设计模式解析

    来自<Objective-C编程之道iOS设计模式解析>一书的摘要总结 一.Prototype 原型模式 定义:使用原型实例指定创建对象的种类,并通过复制这个原型创建新的对象.(<设 ...

  5. Maven下 SpringMvn+thymeleaf 搭建

    1.首先新建一个项目 2.根据以下选项,点击下一步 3.随便输入 4.配置maven的路径 5.点击完成 6.等待所有maven的库文件下载完成后配置pom.xml依赖 <dependency& ...

  6. zabbix 监控项

    监控项 概述 监控项是从主机收集的数据信息. 配置主机后,你需要添加一些监控项以开始获取实际数据. 一个监控项是一个独立的指标.快速添加多个监控项的一种方法是将一个预定义的模板附加到主机.然而,为了优 ...

  7. [QualityCenter]设置工作流脚本-根据某字段是否包含指定字符串来判断其他字段的选值

    需求:当在创建或更改值时,自动判断A字段是否包含B值,然后自动填写相应的内容. 如以下例子: 在脚本编辑器新建一个函数TestPlan_Test_New,然后编写脚本如下: '通过主题判断项目内容   ...

  8. CST,CET,UTC,GMT,DST,Unix时间戳几种常见时间概述与关系(转)

    转自:http://www.cnblogs.com/frontendBY/p/5215785.html 1.UTC: Universal Time Coordinated 协调世界时,又称世界标准时间 ...

  9. maven+jenkins发布环境

    安装java省略,下面是环境变量 export JAVA_HOME=/usr/java/jdk1.8.0_65/ export PATH=$JAVA_HOME/bin:$PATH export CLA ...

  10. 【BZOJ2809】[APIO2012] dispatching(左偏树例题)

    点此看题面 大致题意: 有\(N\)名忍者,每名忍者有三个属性:上司\(B_i\),薪水\(C_i\)和领导力\(L_i\).你要选择一个忍者作为管理者,然后在所有被他管理的忍者中选择若干名忍者,使薪 ...