iOS关于菜单滚动视图实现
菜单滚动视图也是在项目开发过程中比较常用到的功能,先直接看效果图
![]() |
![]() |
实现的效果如下:
当菜单个数的总长度超过一个屏宽度就计算每一个的文字宽度,若没有则只进行一个屏平分,点击菜单项时,滚动的视图位置会随着调整;下面将会把代码贴出来;
1:控制器.h文件的内容
- //
- // myScrollerViewController.h
- // testTest
- //
- // Created by wujunyang on 16/1/22.
- // Copyright © 2016年 wujunyang. All rights reserved.
- //
- #import <UIKit/UIKit.h>
- @protocol myScrollTabBarDelegate <NSObject>
- @optional
- - (void)itemDidSelectedWithIndex:(NSInteger)index;
- @end
- @interface myScrollerViewController : UIViewController
- @property (nonatomic, weak) id <myScrollTabBarDelegate>delegate;
- @property (nonatomic, assign) NSInteger currentIndex;
- @property(nonatomic,copy)NSArray *myTitleArray;
- @end
注意:这边创建的一个delegate,主要是为了当点击事件时把相应的动作往外传,并把相应的菜单索引值传出,方便做其它操作
2:.m控制器的内容
- #import "myScrollerViewController.h"
- #define SCREEN_WIDTH ([UIScreen mainScreen].bounds.size.width)
- #define SCREEN_HEIGHT ([UIScreen mainScreen].bounds.size.height)
- #define TABBAR_TITLE_FONT [UIFont systemFontOfSize:18.f]
- #define NAV_TAB_BAR_HEIGHT 50
- #define NAV_TAB_BAR_Width SCREEN_WIDTH
- @interface myScrollerViewController ()
- //滚动视图
- @property(strong,nonatomic)UIScrollView *myScrollView;
- //滚动下划线
- @property(strong,nonatomic)UIView *line;
- //所有的Button集合
- @property(nonatomic,strong)NSMutableArray *items;
- //所有的Button的宽度集合
- @property(nonatomic,copy)NSArray *itemsWidth;
- //被选中前面的宽度合(用于计算是否进行超过一屏,没有一屏则进行平分)
- @property(nonatomic,assign)CGFloat selectedTitlesWidth;
- @end
- @implementation myScrollerViewController
- - (void)viewDidLoad {
- [super viewDidLoad];
- self.automaticallyAdjustsScrollViewInsets=NO;
- self.view.backgroundColor=[UIColor whiteColor];
- //初始化数组
- if (!self.myTitleArray) {
- self.myTitleArray=@[@"新闻",@"NBA",@"财经",@"科技",@"软件公司",@"健身",@"优秀文摘"];
- }
- self.items=[[NSMutableArray alloc]init];
- self.itemsWidth=[[NSArray alloc]init];
- //初始化滚动
- if (!self.myScrollView) {
- self.myScrollView=[[UIScrollView alloc]initWithFrame:CGRectMake(, , NAV_TAB_BAR_Width, NAV_TAB_BAR_HEIGHT)];
- self.myScrollView.backgroundColor=[UIColor redColor];
- self.myScrollView.showsHorizontalScrollIndicator = NO;
- self.myScrollView.showsVerticalScrollIndicator = NO;
- [self.view addSubview:self.myScrollView];
- }
- //赋值跟计算滚动
- _itemsWidth = [self getButtonsWidthWithTitles:self.myTitleArray];
- CGFloat contentWidth = [self contentWidthAndAddNavTabBarItemsWithButtonsWidth:_itemsWidth];
- self.myScrollView.contentSize = CGSizeMake(contentWidth, );
- self.currentIndex=;
- }
- /**
- * @author wujunyang, 16-01-22 13:01:45
- *
- * @brief 计算宽度
- *
- * @param titles <#titles description#>
- *
- * @return <#return value description#>
- *
- * @since <#version number#>
- */
- - (NSArray *)getButtonsWidthWithTitles:(NSArray *)titles;
- {
- NSMutableArray *widths = [@[] mutableCopy];
- _selectedTitlesWidth = ;
- for (NSString *title in titles)
- {
- CGSize size = [title boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : TABBAR_TITLE_FONT} context:nil].size;
- CGFloat eachButtonWidth = size.width + .f;
- _selectedTitlesWidth += eachButtonWidth;
- NSNumber *width = [NSNumber numberWithFloat:eachButtonWidth];
- [widths addObject:width];
- }
- if (_selectedTitlesWidth < NAV_TAB_BAR_Width) {
- [widths removeAllObjects];
- NSNumber *width = [NSNumber numberWithFloat:NAV_TAB_BAR_Width / titles.count];
- for (int index = ; index < titles.count; index++) {
- [widths addObject:width];
- }
- }
- return widths;
- }
- /**
- * @author wujunyang, 16-01-22 13:01:14
- *
- * @brief 初始化Button
- *
- * @param widths <#widths description#>
- *
- * @return <#return value description#>
- *
- * @since <#version number#>
- */
- - (CGFloat)contentWidthAndAddNavTabBarItemsWithButtonsWidth:(NSArray *)widths
- {
- CGFloat buttonX = ;
- for (NSInteger index = ; index < widths.count; index++)
- {
- UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
- button.frame = CGRectMake(buttonX, , [widths[index] floatValue], NAV_TAB_BAR_HEIGHT);
- button.titleLabel.font = TABBAR_TITLE_FONT;
- button.backgroundColor = [UIColor clearColor];
- [button setTitle:self.myTitleArray[index] forState:UIControlStateNormal];
- [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
- [button addTarget:self action:@selector(itemPressed:) forControlEvents:UIControlEventTouchUpInside];
- [self.myScrollView addSubview:button];
- [_items addObject:button];
- buttonX += [widths[index] floatValue];
- }
- if (widths.count) {
- [self showLineWithButtonWidth:[widths[] floatValue]];
- }
- return buttonX;
- }
- /**
- * @author wujunyang, 16-01-22 13:01:33
- *
- * @brief 选中
- *
- * @param currentIndex 选中索引
- *
- * @since <#version number#>
- */
- - (void)setCurrentIndex:(NSInteger)currentIndex
- {
- _currentIndex = currentIndex;
- UIButton *button = nil;
- button = _items[currentIndex];
- [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
- CGFloat offsetX = button.center.x - NAV_TAB_BAR_Width * 0.5;
- CGFloat offsetMax = _selectedTitlesWidth - NAV_TAB_BAR_Width;
- if (offsetX < || offsetMax < ) {
- offsetX = ;
- } else if (offsetX > offsetMax){
- offsetX = offsetMax;
- }
- [self.myScrollView setContentOffset:CGPointMake(offsetX, ) animated:YES];
- [UIView animateWithDuration:.2f animations:^{
- _line.frame = CGRectMake(button.frame.origin.x + 2.0f, _line.frame.origin.y, [_itemsWidth[currentIndex] floatValue] - 4.0f, _line.frame.size.height);
- }];
- }
- /**
- * @author wujunyang, 16-01-22 13:01:47
- *
- * @brief 增加下划线
- *
- * @param width Button的宽
- *
- * @since <#version number#>
- */
- - (void)showLineWithButtonWidth:(CGFloat)width
- {
- _line = [[UIView alloc] initWithFrame:CGRectMake(2.0f, NAV_TAB_BAR_HEIGHT - 3.0f, width - 4.0f, 3.0f)];
- _line.backgroundColor = [UIColor blueColor];
- [self.myScrollView addSubview:_line];
- }
- - (void)cleanData
- {
- [_items removeAllObjects];
- [self.myScrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
- }
- /**
- * @author wujunyang, 16-01-22 11:01:27
- *
- * @brief 选中时的事件
- *
- * @param button <#button description#>
- *
- * @since <#version number#>
- */
- - (void)itemPressed:(UIButton *)button
- {
- NSInteger index = [_items indexOfObject:button];
- self.currentIndex=index;
- if ([self.delegate respondsToSelector:@selector(itemDidSelectedWithIndex:)]) {
- [self.delegate itemDidSelectedWithIndex:index];
- }
- //修改选中跟没选中的Button字体颜色
- for (int i=; i<_items.count; i++) {
- if (i==index) {
- [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
- }
- else
- {
- [_items[i] setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
- }
- }
- [UIView animateWithDuration:0.1 animations:^{
- button.transform = CGAffineTransformMakeScale(1.1, 1.1);
- } completion:^(BOOL finished) {
- [UIView animateWithDuration:0.1 animations:^{
- button.transform = CGAffineTransformIdentity;
- }completion:^(BOOL finished) {
- }];
- }];
- }
- - (void)didReceiveMemoryWarning {
- [super didReceiveMemoryWarning];
- // Dispose of any resources that can be recreated.
- }
- @end
代码都有进行相应的注解,接下来会对它进行整理,把它移到通用的MVC项目框架中,方便以后项目使用;
若对整理MVC通用的项目框架(意在快速开发时省去很多重复工作)感兴趣可以去下载,Git:https://github.com/wujunyang/MobileProject
二:编辑于2016-01-24
在上面的代码进行扩展,并整理上面的代码封装在一个插件里面实现下面的内容,可以显示跟隐藏弹出窗,弹出窗里面显示出每个菜单项的内容;效果如下:
![]() |
![]() |
使用的代码如下:
- #import "ViewController.h"
- @interface ViewController ()<WJScrollerMenuDelegate>
- @end
- @implementation ViewController
- - (void)viewDidLoad {
- [super viewDidLoad];
- self.automaticallyAdjustsScrollViewInsets=NO;
- // WJScrollerMenuView *vc=[[WJScrollerMenuView alloc]initWithFrame:CGRectMake(0, 64, 320, 50) showArrayButton:NO];
- WJScrollerMenuView *vc=[[WJScrollerMenuView alloc]initWithFrame:CGRectMake(, , [[UIScreen mainScreen] bounds].size.width, ) showArrayButton:YES];
- vc.delegate=self;
- vc.backgroundColor=[UIColor greenColor];
- vc.selectedColor=[UIColor blueColor];
- vc.noSlectedColor=[UIColor blackColor];
- vc.myTitleArray=@[@"第一阶段",@"第二阶段",@"第三阶段",@"第四阶段",@"第五阶段"];
- vc.currentIndex=;
- [self.view addSubview:vc];
- }
- - (void)didReceiveMemoryWarning {
- [super didReceiveMemoryWarning];
- // Dispose of any resources that can be recreated.
- }
- - (void)itemDidSelectedWithIndex:(NSInteger)index
- {
- NSLog(@"选中%d",index);
- }
- @end
插件及实例源代码如下:http://download.csdn.net/detail/u010127054/9416365
最近有个妹子弄的一个关于扩大眼界跟内含的订阅号,每天都会更新一些深度内容,在这里如果你感兴趣也可以关注一下(嘿对美女跟知识感兴趣),当然可以关注后输入:github 会有我的微信号,如果有问题你也可以在那找到我;当然不感兴趣无视此信息;
iOS关于菜单滚动视图实现的更多相关文章
- iOS学习笔记——滚动视图(scrollView)
滚动视图:在根视图中添加UIScrollViewDelegate协议,声明一些对象属性 @interface BoViewController : UIViewController<UIScro ...
- [vue ]滚动视图解决ElementUI NavMenu 导航菜单过长显示的问题
记录一下工作 需求 导航菜单过长的时候会溢出,需要一个像 Tabs 标签页一样的滚动视图容器,可以左右滚动内部视图. 解决方法 由于时间问题,所以直接将 Tabs 源码抽取出来使用. 这里要做一些特殊 ...
- iOS菜单滚动联动内容区域功能实现
平时开发APP中关于此功能还是比较经常碰到,本实例借用三个开源的插件,并对其中一个进行修改调整实现出想要的效果:本文重点介绍修改的内容跟三个插件的运用,这三个插件还可以各自扩展到其它项目的运用: 效果 ...
- iOS开发之视差滚动视图
首先声明一点,由于自己iOS开发经验有限,这里给下面将要实现的效果起名叫视差滚动视图,自己也不知道是否严谨,等以后有经验了,再来更新吧. 一.需求 有的时候我们可能会有这样一种需求,在一个UITabl ...
- iOS 滚动视图的复用问题解决方案
LazyScroll是什么 LazyScrollView 继承自ScrollView,目标是解决异构(与TableView的同构对比)滚动视图的复用回收问题.它可以支持跨View层的复用,用易用方式来 ...
- Xamarin iOS教程之进度条和滚动视图
Xamarin iOS教程之进度条和滚动视图 Xamarin iOS 进度条 进度条可以看到每一项任务现在的状态.例如在下载的应用程序中有进度条,用户可以很方便的看到当前程序下载了多少,还剩下多少.Q ...
- UIScrollView 滚动视图—IOS开发
转自:http://blog.csdn.net/iukey/article/details/7319314 UIScrollView 类负责所有基于 UIKit 的滚动操作. 一.创建 CGRect ...
- 制作滚动视图(ScrollView)
怎样判断是否应当使用滚动视图 所谓的滚动视图,是指一个可以滑动的视窗,视窗大小和位置固定不变,视窗内的内容用户可以通过手指滑动或者拖动滚动天来进行滚动浏览. 滚动视图的目的是为了解决同类内容过多,一个 ...
- iOS无限循环滚动scrollview
经常有园友会问"博主,有没有图片无限滚动的Demo呀?", 正儿八经的图片滚动的Demo我这儿还真没有,今天呢就封装一个可以在项目中直接使用的图片轮播.没看过其他iOS图片无限轮播 ...
随机推荐
- 在当前Server上找某某object,注意只需修改"要找的object"就可以使用
---在当前Server上找某某object,注意只需修改"要找的object"就可以使用EXEC sp_MSforeachdb 'use ? ;IF EXISTS(SELECT ...
- Chrome开发者工具详解(3)-Timeline面板
Chrome开发者工具详解(3)-Timeline面板 注: 这一篇主要讲解面板Timeline,参考了Google的相关文档,主要用于公司内部技术分享.. Timeline面板 Timeline面板 ...
- LeetCode - 51. N-Queens
51. N-Queens Problem's Link ------------------------------------------------------------------------ ...
- C语言学习010:fopen读写文件
在文件input.csv文件中,我们有数据如下 Apple Pear Litchis Pineapple Watermelon 现在我们将input.csv文件下的读取并写入到output.csv文件 ...
- 瀑布式开发、迭代开发、敏捷开发、XP与SCRUM的区别
瀑布式开发.迭代开发,区别[都属于,生命周期模型] 两者都是一种开发模式,就像设计模式一样,考虑的角度不一样,个人感觉谈不到取代一说. 传统的瀑布式开发,也就是从需求到 ...
- MS SQL中使用UPDATE ... INNER JOIN ...
昨天的SQL编程中,有使用到一个方法,就是把一个表某一字段更新至另一个表的字段中去. 实现这个方法,Insus.NET有尝试了几个方法,下面一一分享出来,让大家参考参考. 下面的数据只是模拟了,形式与 ...
- 转型?还是延伸?开源建站系统近乎推整套SNS社区解决方案
转型?还是延伸?开源建站系统近乎推整套SNS社区解决方案 近乎(英文:Spacebuilder),作为.net领域的SNS社区建站系统代表之一,一直在技术开发领域算是兢兢业业,在Discuz!和Php ...
- Eclipse设置风格
如果觉得Eclipse的颜色太刺眼,可以修改背景与字体颜色,方法如下: (1)到http://eclipsecolorthemes.org/下载主题文件,可以选择xml文件或者epf文件: (2)Ec ...
- 关于OpenCart的一个小建议
OpenCart是一套老牌的开源自由B2C电商系统,最近watch了其托管在在github上的项目,发现还是很活跃的,每天都有人反馈bug. 初步的看一下,它是支持在后台管理多个店铺的,而且可以同一个 ...
- Lucene(01)
我的博客园博文地址:http://www.cnblogs.com/tenglongwentian/ Lucene,最新版是Lucene6.2.1,匹配的jdk版本是1.8正式版.这里用jdk7最后一版 ...