第十四篇、OC_新闻查看器
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_新闻查看器的更多相关文章
- 第十四篇 Integration Services:项目转换
		
本篇文章是Integration Services系列的第十四篇,详细内容请参考原文. 简介在前一篇,我们查看了SSIS变量,变量配置和表达式管理动态值.在这一篇,我们使用SQL Server数据商业 ...
 - 【译】第十四篇 Integration Services:项目转换
		
本篇文章是Integration Services系列的第十四篇,详细内容请参考原文. 简介在前一篇,我们查看了SSIS变量,变量配置和表达式管理动态值.在这一篇,我们使用SQL Server数据商业 ...
 - 解剖SQLSERVER 第十四篇    Vardecimals 存储格式揭秘(译)
		
解剖SQLSERVER 第十四篇 Vardecimals 存储格式揭秘(译) http://improve.dk/how-are-vardecimals-stored/ 在这篇文章,我将深入研究 ...
 - Egret入门学习日记 --- 第十四篇(书中 5.4~5.6节 内容)
		
第十四篇(书中 5.4~5.6节 内容) 书中内容: 总结 5.4节 内容重点: 1.如何编写自定义组件? 跟着做: 重点1:如何编写自定义组件? 文中提到了重要的两点. 好,我们来试试看. 第一步, ...
 - Spring Cloud第十四篇 | Api网关Zuul
		
 本文是Spring Cloud专栏的第十四篇文章,了解前十三篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring C ...
 - Python之路【第十四篇】:AngularJS --暂无内容-待更新
		
Python之路[第十四篇]:AngularJS --暂无内容-待更新
 - 跟我学SpringCloud | 第十四篇:Spring Cloud Gateway高级应用
		
SpringCloud系列教程 | 第十四篇:Spring Cloud Gateway高级应用 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 ...
 - SpringBoot第二十四篇:应用监控之Admin
		
作者:追梦1819 原文:https://www.cnblogs.com/yanfei1819/p/11457867.html 版权声明:本文为博主原创文章,转载请附上博文链接! 引言 前一章(S ...
 - Hibernate(十四篇)
		
(一)Hibernate简介 (二)hibernate配置管理 (三)Hibernate对象-关系映射文件 (四)Hibernate API详解 (五)Hibernate一级缓存 (六)Hiberna ...
 
随机推荐
- bzoj1004 [HNOI2008]Cards【Burnside/Polya】
			
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1004 一道好题,但并不是好在融合了三个“考点”(计数,背包dp,逆元),其实背包dp以及求逆 ...
 - P2066 机器分配 (DP+DP输出)
			
题目描述 总公司拥有高效设备M台,准备分给下属的N个分公司.各分公司若获得这些设备,可以为国家提供一定的盈利.问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值.其中M≤15,N≤10.分 ...
 - Helvetic Coding Contest 2016 online mirror F1
			
Description Heidi has finally found the mythical Tree of Life – a legendary combinatorial structure ...
 - oracle的存储过程优缺点
			
oracle的存储过程优缺点 1.存储过程可以使得程序执行效率更高.安全性更好,因为过程建立之后 已经编译并且储存到数据库,直接写sql就需要先分析再执行因此过程效率更高,直接写sql语句会带来安全性 ...
 - .NET Memcached Client 扩展获取所有缓存Key
			
.NET Memcached Client默认实现中并没有获取所有已经缓存Key的方法,但在业务中有时候需求中需要通过正则删除符合条件的缓存内容,所以就要通过读取已经缓存Key进行相关的匹配,然后删除 ...
 - CAS操作
			
CAS操作: Compare and Swap,比较并操作,CPU指令,在大多数处理器架构,包括IA32.Space中采用的都是CAS指令,CAS的语义是“我认为V的值应该为A,如果是,那么将V的值更 ...
 - JavaScript跨域资源请求(CORS)解决方案
			
跨域:当协议.主域名.子域名.端口号中任意一个不相同时都不算同一个域,而在不同域之间请求数据即为跨域请求.解决方法有以下几种(如有错误欢迎指出)以请求图片url为例: 1.通过XMLHttpReque ...
 - 牛客网Java刷题知识点之进程和线程的区别
			
不多说,直接上干货! https://www.nowcoder.com/ta/review-java/review?tpId=31&tqId=21079&query=&asc= ...
 - python socket客户端
			
#./usr/bin/env python#coding:utf-8import socket#.....ip...print ('server start...')ip_port = ('144.3 ...
 - linux安装jdk7步骤
			
linux安装jdk7步骤: 1.首先使用命令查看linux系统版本号: lsb_release -a 2.下载对应的jdk版本,笔者使用的是jdk-7u79-linux-x64.tar.gz: 3. ...