顶部滚动菜单栏

封装了2个类  github地址:https://github.com/PengHongMiao/-demo.git

//

//  PHTopTitleView.h

//  顶部滚动菜单

//

//  Created by 123 on 16/9/10.

//  Copyright © 2016年 彭洪. All rights reserved.

//

#import <UIKit/UIKit.h>

@class PHTopTitleView;

@protocol PHTopTitleViewDelegate <NSObject>

- (void)topTitleView:(PHTopTitleView *)topTitleView didSelectTitleAtIndex:(NSInteger)index;

@end

@interface PHTopTitleView : UIScrollView

/** 禁止标题数组 */

@property (nonatomic,strong) NSArray *staticTitleArr;

/** 滚动标题数组 */

@property (nonatomic,strong) NSArray *scrollTitleArr;

/** 存入所有Label */

@property (nonatomic,strong) NSMutableArray *allTitleLabel;

@property (nonatomic,weak) id<PHTopTitleViewDelegate>delegate;

/** 类方法 */

+ (instancetype)topTitleViewWithFrame:(CGRect)frame;

#pragma mark 给外界ScrollView提供的方法以及自身方法实现

/** 禁止标题选中颜色改变以及指示器位置变化 */

- (void)staticTitleLabelSelected:(UILabel *)label;

/** 滚动标题选中颜色以及指示器位置变化 */

- (void)scrollTitleLabelSelected:(UILabel *)label;

/** 滚动标题选中居中 */

- (void)scrollTitleLabelSelectedCenter:(UILabel *)centerLabel;

#pragma mark 给外界ScrollView提供的方法

/** 滚动ScrollView 让文字呈现渐变效果 */

- (void)scrollTitleLabelSelectedChangeTextColorFadeScrollView:(UIScrollView *)scrollView;

@end

//

//  PHTopTitleView.m

//  顶部滚动菜单

//

//  Created by 123 on 16/9/10.

//  Copyright © 2016年 彭洪. All rights reserved.

//

#import "PHTopTitleView.h"

#import "UIView+PHExtension.h"

#define labelFontOfSize    [UIFont systemFontOfSize:17]

#define SCREEN_Width    [UIScreen mainScreen].bounds.size.width

#define selectedTitleIndicatorViewColor    [UIColor redColor]

@interface PHTopTitleView ()

/** 静止标题 */

@property (nonatomic,strong) UILabel *staticTitleLabel;

/** 滚动标题 */

@property (nonatomic,strong) UILabel *scrollTitleLabel;

/** 选中标题时Label */

@property (nonatomic,strong) UILabel *selectedTitleLabel;

/** 指示器 */

@property (nonatomic,strong) UIView *indicatorView;

@end

@implementation PHTopTitleView

/** label之间的间距 */

static CGFloat const labelMargin = 15;

/** 指示器的高度 */

static CGFloat const indicatorHeight = 3;

- (NSMutableArray *)allTitleLabel {

if (_allTitleLabel == nil) {

_allTitleLabel = [[NSMutableArray alloc] init];

}

return _allTitleLabel;

}

- (instancetype)initWithFrame:(CGRect)frame {

self = [super initWithFrame:frame];

if (self) {

self.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.9];

self.showsHorizontalScrollIndicator = NO;

self.bounces = NO;//弹性设置

}

return self;

}

+ (instancetype)topTitleViewWithFrame:(CGRect)frame {

return [[self alloc] initWithFrame:frame];

}

/**

*  计算文字尺寸

*

*  @param text    需要计算尺寸的文字

*  @param font    文字的字体大小

*  @param maxSize 文字的最大尺寸

*

*  @return label的大小

*/

- (CGSize)sizeWithText:(NSString *)text font:(UIFont *)font maxSize:(CGSize)maxSize {

NSDictionary *attributes = @{NSFontAttributeName:font};

return [text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil].size;

}

#pragma mark 重写禁止标题数组的setter方法

- (void)setStaticTitleArr:(NSArray *)staticTitleArr {

_staticTitleArr = staticTitleArr;

//计算ScrollView的宽度

CGFloat scrollViewWidth = self.frame.size.width;

CGFloat labelX = 0;

CGFloat labelY = 0;

CGFloat labelW = scrollViewWidth / self.staticTitleArr.count;

CGFloat labelH = self.frame.size.height - indicatorHeight;

for (NSInteger j=0; j<self.staticTitleArr.count; j++) {

//创建静止标题时label

self.staticTitleLabel = [[UILabel alloc] init];

_staticTitleLabel.userInteractionEnabled = YES;

_staticTitleLabel.text = self.staticTitleArr[j];

_staticTitleLabel.textAlignment = NSTextAlignmentCenter;

_staticTitleLabel.tag = j;

//设置高亮文字颜色

_staticTitleLabel.highlightedTextColor = selectedTitleIndicatorViewColor;

//计算staticTitleLabel的x值

labelX = j*labelW;

_staticTitleLabel.frame = CGRectMake(labelX, labelY, labelW, labelH);

//添加到titlesLabels数组

[self.allTitleLabel addObject:_staticTitleLabel];

//添加点按手势

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(staticTitleClick:)];

[_staticTitleLabel addGestureRecognizer:tap];

//默认选中0个label

if (j == 0) {

[self staticTitleClick:tap];

}

[self addSubview:_staticTitleLabel];

}

//取出第一个子空间

UILabel *firstLabel = self.subviews.firstObject;

//添加指示器

self.indicatorView = [[UIView alloc] init];

_indicatorView.backgroundColor = selectedTitleIndicatorViewColor;

_indicatorView.PH_height = indicatorHeight;

_indicatorView.PH_y = self.frame.size.height - indicatorHeight;

[self addSubview:_indicatorView];

//指示器默认在第一个选中位置

CGSize labelSize = [self sizeWithText:firstLabel.text font:labelFontOfSize maxSize:CGSizeMake(MAXFLOAT, labelH)];

_indicatorView.PH_width = labelSize.width;

_indicatorView.PH_centerX = firstLabel.PH_centerX;

}

/** scrollTitleClick的点击事件 */

- (void)scrollTitleClick:(UITapGestureRecognizer *)tap {

//0.获取选中的label

UILabel *selLabel = (UILabel *)tap.view;

//1.标题颜色变成红色 设置高亮状态下的颜色 以及指示器的位置

[self scrollTitleLabelSelected:selLabel];

//让选中的标题居中

[self scrollTitleLabelSelectedCenter:selLabel];

//代理方法实现

NSInteger index = selLabel.tag;

if ([self.delegate respondsToSelector:@selector(topTitleView:didSelectTitleAtIndex:)]) {

[self.delegate topTitleView:self didSelectTitleAtIndex:index];

}

}

/** 滚动标题选中颜色改变以及指示器位置变化 */

- (void)scrollTitleLabelSelected:(UILabel *)label {

//取消高亮

_selectedTitleLabel.highlighted = NO;

//颜色回复

_selectedTitleLabel.textColor = [UIColor blackColor];

//高亮

label.highlighted = YES;

_selectedTitleLabel = label;

//改变指示器位置

[UIView animateWithDuration:0.20 animations:^{

self.indicatorView.PH_width = label.PH_width - 2*labelMargin;

self.indicatorView.PH_centerX = label.PH_centerX;

}];

}

/** 滚动标题选中居中 */

- (void)scrollTitleLabelSelectedCenter:(UILabel *)centerLabel {

//计算偏移量

CGFloat offsetX = centerLabel.center.x - SCREEN_Width * 0.5;

if (offsetX < 0) {

offsetX = 0;

}

//获取最大滚动范围

CGFloat maxOffsetX = self.contentSize.width - SCREEN_Width;

if (offsetX>maxOffsetX) {

offsetX = maxOffsetX;

}

//滚动标题滚动条

[self setContentOffset:CGPointMake(offsetX, 0) animated:YES];

}

#pragma mark 给外界ScrollView提供的方法

- (void)scrollTitleLabelSelectedChangeTextColorFadeScrollView:(UIScrollView *)scrollView {

//当前label的位置

CGFloat currentPage = scrollView.contentOffset.x / scrollView.bounds.size.width;

NSInteger leftIndex = currentPage;

NSInteger rightIndex = leftIndex + 1;

//获取左边label

UILabel *leftLabel = self.allTitleLabel[leftIndex];

//获取右边label

UILabel *rightLabel;

if (rightIndex < self.allTitleLabel.count - 1) {

rightLabel = self.allTitleLabel[rightIndex];

}

//计算下右边缩放比例

CGFloat rightScale = currentPage - leftIndex;

//计算下左边缩放比例

CGFloat leftScale = 1 - rightScale;

//设置文字颜色渐变

leftLabel.textColor = [UIColor colorWithRed:leftScale green:0 blue:0 alpha:1];

rightLabel.textColor = [UIColor colorWithRed:rightScale green:0 blue:0 alpha:1];

}

- (void)staticTitleClick:(UITapGestureRecognizer *)tap {

}

@end

//

//  UIView+PHExtension.h

//  顶部滚动菜单

//

//  Created by 123 on 16/9/10.

//  Copyright © 2016年 彭洪. All rights reserved.

//

#import <UIKit/UIKit.h>

@interface UIView (PHExtension)

@property (nonatomic,assign) CGFloat PH_x;

@property (nonatomic,assign) CGFloat PH_y;

@property (nonatomic,assign) CGFloat PH_width;

@property (nonatomic,assign) CGFloat PH_height;

@property (nonatomic,assign) CGFloat PH_centerX;

@property (nonatomic,assign) CGFloat PH_centerY;

@property (nonatomic,assign) CGSize PH_size;

@end

//

//  UIView+PHExtension.m

//  顶部滚动菜单

//

//  Created by 123 on 16/9/10.

//  Copyright © 2016年 彭洪. All rights reserved.

//

#import "UIView+PHExtension.h"

@implementation UIView (PHExtension)

#pragma mark 设置器方法

- (void)setPH_x:(CGFloat)PH_x {

CGRect frame = self.frame;

frame.origin.x +=PH_x;

self.frame = frame;

}

- (void)setPH_y:(CGFloat)PH_y {

CGRect frame = self.frame;

frame.origin.y += PH_y;

self.frame = frame;

}

- (void)setPH_width:(CGFloat)PH_width {

CGRect frame = self.frame;

frame.size.width += PH_width;

self.frame = frame;

}

- (void)setPH_height:(CGFloat)PH_height {

CGRect frame = self.frame;

frame.size.height += PH_height;

self.frame = frame;

}

- (void)setPH_centerX:(CGFloat)PH_centerX {

CGPoint center = self.center;

center.x += PH_centerX;

self.center = center;

}

- (void)setPH_centerY:(CGFloat)PH_centerY {

CGPoint center = self.center;

center.y += PH_centerY;

self.center = center;

}

- (void)setPH_size:(CGSize)PH_size {

CGRect frame = self.frame;

frame.size = PH_size;

self.frame = frame;

}

#pragma mark 获取器方法

- (CGFloat)PH_x {

return self.frame.origin.x;

}

- (CGFloat)PH_y {

return self.frame.origin.y;

}

- (CGFloat)PH_width {

return self.frame.size.width;

}

- (CGFloat)PH_height {

return self.frame.size.height;

}

- (CGFloat)PH_centerX {

return self.center.x;

}

- (CGFloat)PH_centerY {

return self.center.y;

}

- (CGSize)PH_size {

return self.frame.size;

}

+ (instancetype)PH_ViewFromXib {

return [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self) owner:nil options:nil].lastObject;

}

@end

时间: 2024-10-05 22:49:36

顶部滚动菜单栏的相关文章

Android中仿淘宝首页顶部滚动自定义HorizontalScrollView定时水平自动切换图片

Android中仿淘宝首页顶部滚动自定义HorizontalScrollView定时水平自动切换图片 自定义ADPager 自定义水平滚动的ScrollView效仿ViewPager 当遇到要在ViewPager中添加多张网络请求图片的情况下,不能进行复用,导致每次都要重新去求情已经请求过的数据致使流量数据过大 自定义的数据结构解决了这个问题,固定传递的图片数据之后进行统一请求,完成后进行页面切换数据复用 代码中涉及网络请求是用的Volley网络请求框架 PicCarousel是网络数据请求的U

Sublime Text编辑器如何隐藏顶部的菜单栏

隐藏前: 解决办法: 1.按住Ctrl+Shifp+p,出现一个框,在框里输入“view:”,出现了如下界面 2.选择:“View:Toggle Menu”即可.结果为: 大功告成!!!!

IOS UIScrollView + UIButton 实现页面和顶部标签页水平滚动效果

很长一段时间没有写博客了,最近在学习iOS开发,看了不少的代码,自己用UIScrollView和UIButton实现了水平滚动的效果,有点类似于今日头条的主界面框架,效果如下: 代码如下: MyScrollView.h #import <UIKit/UIKit.h> #import "MySegementView.h" @interface MyScrollView : UIView<UIScrollViewDelegate> - (instancetype)

jquery 页眉单行信息滚动显示

JSP: 以下是控制滚动的样式,将滚动的内容查询出来,放在一个div 或者别的容器里面,我这里使用的是<dt> <style> #newCglist{width:300px;height:14px;line-height:14px;overflow:hidden} #newCglist li{height:14px;padding-left:10px;} </style> 以下是滚动内容展示的容器 <dt class="positionrel"

上拉、下拉无限滚动组件-pc端

场景: web项目,聊天记录历史搜索.需要支持上拉无限加载,下拉无限加载. 目标: 支持所需场景:可配置. 难点: 顶部无限滚动很麻烦,网上没找着好的解决方案.刚开始 顶部也想使用 IntersectionObserver 特性来做,但二次触发比较麻烦,后来改用监听 scroll 事件.问题又来了,滚动条一直处于顶部,无法保持原来的位置. 本例解决方案是:利用 scrollIntoViewIfNeeded 特性,在组装列表完成后,手动调用,使其滚动到 原来的列表项位置. 成品效果: 凑合能用,O

JavaScript学习总结【6】、JS BOM

1.BOM简介. 所谓的BOM即浏览器对象模型(Browser Object Model).BOM赋予了JS操作浏览器的能力,即window操作.DOM则用于创建删除节点,操作HTML文档.BOM尚无正式的标准,导致各浏览器对于BOM方法的支持各有不同,因此需要具体问题具体对待. 2.window对象. window对象是BOM的核心,window对象指当前的浏览器窗口.所有JS全局对象.函数以及变量都属于window对象.全局变量是window对象的属性.全局函数是window对象的方法.甚至

Linux - 可视化菜单界面设计

优化屏幕刷新 问题 刷新多个窗体需要一些繁琐,在一个慢速的链接上,屏幕的绘制相当的慢 目标就是要尽量减少要在屏幕上的绘制的字符数 基本函数 int wnoutrefresh(WINDOW *window_ptr); 决定哪些字符需要发送到屏幕,但是并不实际的发送 int doupdate(void); 向终端发送实际的改变 说明 如果只是简单地调用wnoutrefresh,其后立即调用doupdate,其效果就如同调用wrefresh一样 如果希望重新绘制一个窗体栈,可以在每一个窗体(以正确的顺

实验十四 Swing图形界面组件

实验十四  Swing图形界面组件 实验时间 20178-11-29 1.实验目的与要求 (1) 掌握GUI布局管理器用法: (2) 掌握各类Java Swing组件用途及常用API: 2.实验内容和步骤 实验1: 导入第12章示例程序,测试程序并进行组内讨论. 测试程序1 在elipse IDE中运行教材479页程序12-1,结合运行结果理解程序: 掌握各种布局管理器的用法: 理解GUI界面中事件处理技术的用途. 在布局管理应用代码处添加注释: 测试结果: 这个程序是一个网格布局,网格布局像一

centos官网镜像下载方法

1.CentoS简介 CentOS(Community Enterprise Operating System,社区企业操作系统)是一个基于Red Hat Linux 提供的可自由使用源代码的企业级Linux发行版本,以高效.稳定著称.它使用与Red Hat相同的源代码编译而成,而且是开源免费的,因此有些要求高度稳定性的服务器以CentOS替代商业版的Red Hat Enterprise Linux使用,是很多中小服务器站点的首选.CentOS拥有Red Hat的所有功能,它们的不同之处在于Ce