第十四篇、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 ...
随机推荐
- libaudit_plugin.so安装
#上传audit到mysql的plugin目录vim /etc/my.cnfplugin-load=AUDIT=libaudit_plugin.soaudit_json_file=1audit_jso ...
- 08.Spring Bean 解析 - BeanDefinitionDocumentReader
基本概念 BeanDefinitionDocumentReader ,该类的作用有两个,完成 BeanDefinition 的解析和注册 . 解析:其实是解析 Ddocument 的内容并将其添加到 ...
- ACdream 1236 Burning Bridges 割边 + 去重边
题目就是求一副图的割边,然后对于那些有重复的边的,不能算做割边. 思路就是每次加入一条边的时候,判断这条边是否存在过,存在过的话,就把那条边设为inf,表示不能作为割边.于是有了这样的代码 #incl ...
- Java local 转UTC时间
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; impor ...
- Spark 概述
Spark 是什么? ● 官方文档解释:Apache Spark is a fast and general engine for large-scale data processing. 通俗的理解 ...
- phpcms如何调用某一组图里的所有图片
{pc:get sql="select * from v9_picture_data where id = '$id'"} {loop $data $n $r} {loop str ...
- mac-httpd
mac 的httpd mac 自带了apache2, 但是不推荐使用, 因为它的目录在/Library/WebServer/Documents/下 使用brew install apache-http ...
- @b.windows.last.use
@b.windows.last.use @b.windows.first.use be_true 一般用在step文件中
- 《Head First 设计模式》之策略模式——鸭子行为
策略模式(Strategy Pattern) ——定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户. (每个功能的多种实现成为一个算法族,这些算法族被分别封装 ...
- javascript中call()、apply()、bind()的用法理解
一.bind的用法 第一个:obj.showInfo('arg','arg_18');中传的2个参数通过showInfo方法改变的是obj下中的name和age 第二个:obj.showInfo.bi ...