iOS 之模拟网易新闻主页的滚动效果
最近下载了一个网易新闻的APP客户端,觉得新闻主页的滚动效果不错,每个标题都对应一个版面,如图
不好意思图有点大(是在网上下的,我就懒得截图了)
于是就模仿它写了一个demo程序.代码如下所示...
MainViewController是APP的主界面,负责初始化头部的scrollView以及底下的scrollView,在AppDelegate实现类中初始化该对象并设置根视图为它。
// MainViewController.h
// test4101
//
// Created by silicon on 14-4-10.
// Copyright (c) 2014年 silicon. All rights reserved.
// #import <UIKit/UIKit.h> @interface MainViewController : UIViewController @end</pre><br>
<br> <pre code_snippet_id="346326" snippet_file_name="blog_20140515_10_816282"></pre><pre code_snippet_id="346326" snippet_file_name="blog_20140515_29_2384508" name="code" class="objc"></pre><pre code_snippet_id="346326" snippet_file_name="blog_20140515_29_2384508" name="code" class="objc"></pre><pre code_snippet_id="346326" snippet_file_name="blog_20140515_29_2384508" name="code" class="objc"></pre><pre code_snippet_id="346326" snippet_file_name="blog_20140515_29_2384508" name="code" class="objc"></pre><pre code_snippet_id="346326" snippet_file_name="blog_20140515_13_2540906" name="code" class="objc">//
// MainViewController.m
// test4101
//
// Created by silicon on 14-4-10.
// Copyright (c) 2014年 silicon. All rights reserved.
// #import "MainViewController.h"
#import "TopScrollView.h"
#import "ButtomScrollView.h" @interface MainViewController () @end @implementation MainViewController - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{ self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self;
} - (void)viewDidLoad
{ [super viewDidLoad]; // Do any additional setup after loading the view from its nib. UIImageView *topShadowImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 44, 320, 5)]; [topShadowImageView setImage:[UIImage imageNamed:@"top_background_shadow.png"]]; [self.view addSubview:topShadowImageView]; TopScrollView *topScrollView = [TopScrollView getInstance]; ButtomScrollView *buttomScrollView = [ButtomScrollView getInstance]; topScrollView.titleArray = @[@"苹果中国", @"iCloud", @"新浪微薄", @"维基百科", @"百度", @"中国雅虎", @"新闻", @"流行"]; buttomScrollView.viewNameArray = @[@"苹果中国", @"iCloud", @"新浪微薄", @"维基百科", @"百度", @"中国雅虎", @"新闻", @"流行"]; [self.view addSubview:topScrollView]; [self.view addSubview:buttomScrollView]; [topScrollView initWithTitleButtons]; [buttomScrollView initWithViews];
} - (void)didReceiveMemoryWarning
{ [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.
} @end
TopScrollView这个类主要用于控制上面标题的滚动逻辑,通过initWithTitleButtons这个函数来初始化按钮(包括按钮的标题,tag, 响应事件,坐标)并且将按钮的
x坐标以及宽度存储到容器中保存(相应读取可以按照控件的tag来取)。
selectNameButton用来控制按钮切换以及底部试图同步切换的逻辑。
adjustScrollViewContentX函数用于控制当按钮的x坐标超过了屏幕的最大宽时,调整按钮的x坐标至屏幕可见范围。
// TopScrollView.h
// test4101
//
// Created by silicon on 14-4-10.
// Copyright (c) 2014年 silicon. All rights reserved.
// #import <UIKit/UIKit.h> @interface TopScrollView : UIScrollView <UIScrollViewDelegate>{ NSArray *titleArray; NSInteger userSelectedButtonTag; NSInteger scrollViewSelectedID; UIImageView *shadowImage;
} @property (nonatomic, retain) NSArray *titleArray; @property (nonatomic, retain) NSMutableArray *buttonWithArray; @property (nonatomic, retain) NSMutableArray *buttonOrignXArray; @property (assign) NSInteger scrollViewSelectedID; @property (assign) NSInteger userSelectedButtonTag; + (TopScrollView *)getInstance; //加载顶部标题
- (void)initWithTitleButtons; - (void)setButttonUnSelect; - (void)setButtonSelect; - (void)setScrollViewContentOffset; @end
// TopScrollView.m
// test4101
//
// Created by silicon on 14-4-10.
// Copyright (c) 2014年 silicon. All rights reserved.
// #import "TopScrollView.h"
#import "ButtomScrollView.h" @implementation TopScrollView
@synthesize titleArray;
@synthesize userSelectedButtonTag;
@synthesize scrollViewSelectedID;
@synthesize buttonOrignXArray;
@synthesize buttonWithArray; + (TopScrollView *)getInstance{ static TopScrollView *instance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [[self alloc] initWithFrame:CGRectMake(0, 20, CONTENTSIZEX, 44)]; }); return instance;
} - (id)initWithFrame:(CGRect)frame
{ self = [super initWithFrame:frame]; if (self) { // Initialization code self.delegate = self; self.backgroundColor = [UIColor clearColor]; self.pagingEnabled = NO; self.showsHorizontalScrollIndicator = NO; self.showsVerticalScrollIndicator = NO; userSelectedButtonTag = 100; scrollViewSelectedID = 100; self.buttonOrignXArray = [[NSMutableArray alloc] init]; self.buttonWithArray = [[NSMutableArray alloc] init]; } return self;
} - (void)initWithTitleButtons{ float xPos = 5.0f; for(int i = 0; i < [self.titleArray count]; i++){ UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; NSString *title = [self.titleArray objectAtIndex:i]; [button setTag:i + 100]; if(i == 0){ button.selected = YES; } [button setTitle:title forState:UIControlStateNormal]; [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; [button addTarget:self action:@selector(selectNameButton:) forControlEvents:UIControlEventTouchUpInside]; int buttonWidth = [title sizeWithFont:button.titleLabel.font constrainedToSize:CGSizeMake(150, 30) lineBreakMode:NSLineBreakByClipping].width; button.frame = CGRectMake(xPos, 9, buttonWidth + BUTTONGAP, 30); [buttonOrignXArray addObject:@(xPos)]; //按钮的X坐标 xPos += buttonWidth + BUTTONGAP; //按钮的宽度 [self.buttonWithArray addObject:@(button.frame.size.width)]; [self addSubview:button]; } //视图的位移 self.contentSize = CGSizeMake(xPos, 44); shadowImage = [[UIImageView alloc] initWithFrame:CGRectMake(BUTTONGAP, 0, [[self.buttonWithArray objectAtIndex:0] floatValue], 44)]; [shadowImage setImage:[UIImage imageNamed:@"red_line_and_shadow.png"]]; [self addSubview:shadowImage];
} - (void)selectNameButton:(UIButton *)sender{ [self adjustScrollViewContentX:sender]; //如果跟换按钮 if(sender.tag != userSelectedButtonTag){ UIButton *mybutton = (UIButton *)[self viewWithTag:userSelectedButtonTag]; mybutton.selected = NO; userSelectedButtonTag = sender.tag; } //按钮选中状态 if(!sender.selected){ sender.selected = YES; [UIView animateWithDuration:0.25 animations:^{ [shadowImage setFrame:CGRectMake(sender.frame.origin.x, 0, [[self.buttonWithArray objectAtIndex:sender.tag - 100] floatValue], 44)]; } completion:^(BOOL finished) { if(finished){ //页面出现 [[ButtomScrollView getInstance] setContentOffset:CGPointMake((sender.tag - 100) * 320, 0) animated:YES]; //滑动选择页面 scrollViewSelectedID = sender.tag; } }]; }
} //调整滚动按钮显示
- (void)adjustScrollViewContentX:(UIButton *)sender{ float originX = [[self.buttonOrignXArray objectAtIndex:(sender.tag - 100)] floatValue]; float width = [[self.buttonWithArray objectAtIndex:(sender.tag - 100)] floatValue]; if((sender.frame.origin.x - self.contentOffset.x) > (CONTENTSIZEX - (BUTTONGAP + width))){ [self setContentOffset:CGPointMake(originX - 30, 0) animated:YES]; } if((sender.frame.origin.x - self.contentOffset.x) < 5){ [self setContentOffset:CGPointMake(originX, 0) animated:YES]; }
} - (void)setButttonUnSelect{ UIButton *button = (UIButton *)[self viewWithTag:scrollViewSelectedID]; button.selected = NO;
} - (void)setButtonSelect{ //选中滑动的按钮 UIButton *button = (UIButton *)[self viewWithTag:scrollViewSelectedID]; [UIView animateWithDuration:0.25 animations:^{ [shadowImage setFrame:CGRectMake(button.frame.origin.x, 0, [[self.buttonWithArray objectAtIndex:button.tag - 100] floatValue], 44)]; } completion:^(BOOL finished) { if(finished){ if(!button){ button.selected = YES; userSelectedButtonTag = button.tag; } } }];
} - (void)setScrollViewContentOffset{ float originX = [[self.buttonOrignXArray objectAtIndex:(scrollViewSelectedID - 100)] floatValue]; float width = [[self.buttonWithArray objectAtIndex:(scrollViewSelectedID - 100)] floatValue]; if((originX - self.contentOffset.x) > (CONTENTSIZEX - (BUTTONGAP + width))){ [self setContentOffset:CGPointMake(originX - 30, 0) animated:YES]; } if(originX - self.contentOffset.x < 5){ [self setContentOffset:CGPointMake(originX, 0) animated:YES]; }
} @end
ButtomScrollView这个类主要控制底部视图的显示, adjustTopScrollViewButton函数用于调整按钮的显示,相关逻辑见源码(打字打的有点手酸)...
// ButtomScrollView.h
// test4101
//
// Created by silicon on 14-4-10.
// Copyright (c) 2014年 silicon. All rights reserved.
// #import <UIKit/UIKit.h> @interface ButtomScrollView : UIScrollView<UIScrollViewDelegate>{ NSMutableArray *viewNameArray; CGFloat userContentOffsetX; BOOL isLeftScroll;
} @property (nonatomic, retain) NSArray *viewNameArray; + (ButtomScrollView *)getInstance; - (void)initWithViews; - (void)loadData; @end
// ButtomScrollView.m
// test4101
//
// Created by silicon on 14-4-10.
// Copyright (c) 2014年 silicon. All rights reserved.
// #import "ButtomScrollView.h"
#import "TopScrollView.h" @implementation ButtomScrollView
@synthesize viewNameArray; - (id)initWithFrame:(CGRect)frame
{ self = [super initWithFrame:frame]; if (self) { // Initialization code self.delegate = self; self.backgroundColor = [UIColor lightGrayColor]; self.pagingEnabled = YES; self.userInteractionEnabled = YES; self.bounces = NO; self.showsHorizontalScrollIndicator = NO; self.showsVerticalScrollIndicator = NO; userContentOffsetX = 0; } return self;
} + (ButtomScrollView *)getInstance{ static ButtomScrollView *instance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [[self alloc] initWithFrame:CGRectMake(0, 64, CONTENTSIZEX, 500)]; }); return instance;
} - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{ userContentOffsetX = scrollView.contentOffset.x;
} - (void)scrollViewDidScroll:(UIScrollView *)scrollView{ if(userContentOffsetX < scrollView.contentOffset.x){ isLeftScroll = YES; }else{ isLeftScroll = NO; }
} - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{ [self adjustTopScrollViewButton:scrollView]; [self loadData];
} //调整按钮显示
- (void)adjustTopScrollViewButton:(UIScrollView *)scrollView{ [[TopScrollView getInstance] setButttonUnSelect]; [TopScrollView getInstance].scrollViewSelectedID = POSITION + 100; [[TopScrollView getInstance] setButtonSelect]; [[TopScrollView getInstance] setScrollViewContentOffset];
} - (void)initWithViews{ for(int i = 0; i < [viewNameArray count]; i++){ UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(50 + 320*i, 100, 320, self.frame.size.height - 44)]; label.tag = 200 + i; if(i == 0){ label.text = [viewNameArray objectAtIndex:i]; } [self addSubview:label]; } self.contentSize = CGSizeMake(320*[viewNameArray count], self.frame.size.height - 44);
} - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{ [self loadData];
} - (void)loadData{ CGFloat pageWidth = self.frame.size.width; int page = floor((self.contentOffset.x - pageWidth/viewNameArray.count)/pageWidth) + 1; UILabel *label = (UILabel *)[self viewWithTag:page + 200]; label.text = [NSString stringWithFormat:@"%@", [viewNameArray objectAtIndex:page]];
}
BTW,别忘了在Prefix文件中加入以下宏。
// Prefix header
//
// The contents of this file are implicitly included at the beginning of every source file.
// #import <Availability.h> #ifndef __IPHONE_3_0
#warning "This project uses features only available in iOS SDK 3.0 and later."
#endif #define BUTTONGAP 10
#define CONTENTSIZEX 320
#define POSITION (int)(scrollView.contentOffset.x/320) #ifdef __OBJC__ #import <UIKit/UIKit.h> #import <Foundation/Foundation.h>
#endif
好了,以上就是该demo的源码,运行一下,如下图所以.
点击iCloud按钮,下面也随即切换到iCloud。
以上就是今天这篇文章所讲的全部内容了,希望大家指出问题,一起进步啊!
iOS 之模拟网易新闻主页的滚动效果相关推荐
- iOS开发 剖析网易新闻标签栏视图切换(addChildViewController属性介绍)
iOS开发 剖析网易新闻标签栏视图切换(addChildViewController属性介绍) 本来仅仅是打算介绍一下addChildViewController这种方法的,正好今天朋友去换工作面试问 ...
- 模仿网易新闻客户端的滚动菜单
模仿网易新闻客户端的滚动菜单,点击菜单的时候有放大标题的动画效果.demo地址:https://github.com/BigHub/ScrollMenuViewTest 需要用到facebook的开源 ...
- IOS开发——仿网易新闻客户端
IOS开发--仿网易新闻客户端 本文没有内容,传个资源 衔接地址:http://download.csdn.net/detail/u012881779/7152281 左侧导航部分: 新闻版块 订阅版 ...
- IOS开发--仿制网易新闻
学习来源:袁峥老师的<快速集成App中顶部标题滚动条> 此次博文写的是按需求分析写代码,思路条理性杠杠的,可以提高的编码实现速度哦. 效果: 根据这个网易新闻的界面,需求分析: 需要的对象 ...
- 尚硅谷 模拟网易新闻列表练习
要求 网址:https://news.163.com/ 代码 <!DOCTYPE html> <html lang="en"><head>< ...
- 仿网易新闻评论的楼层效果
评论在很多app中都会用到,最常见的就是网易新闻中的评论了,所以今天就研究了一下这个,先看看网易的效果图吧. 这么一个评论的列表,想必都会做吧.一个ListView之类的控件,里面的item也是一个较 ...
- 仿网易新闻评论“盖楼”效果实现
前言 各位应该对黄易新闻比较熟悉,其中评论区一般都会出现一些盖楼的神评论,今天的主题就是仿照做一个有盖楼效果的评论列表. 首先上图给大家看下效果: 思路 数据结构设计 首先分析看下评论的结构,仔细观摩 ...
- Android网易新闻评论盖楼效果的实现
转子:http://xie2010.blog.163.com/blog/static/211317365201411041930806/
- 动画特效十五:网易新闻之头部导航切换效果
本人录制技术视频地址:https://edu.csdn.net/lecturer/1899 欢迎观看. 这一节继续和大家探讨iOS中的动画效果,由于网易新闻中的动画效果比较多,所以我分两个章节进行介绍 ...
- 模仿网易新闻客户端(RSS版)(一)
一.摘要 这几天找工作闲来没事,偶然在一个论坛上面看到有人模拟网易新闻客户端首页顶部那个组件效果,一时兴起,也来自己动手完整地模拟一个,包括顶部的特效组件和底部的类似于TabHost的组件.下面就动手 ...
最新文章
- 吊炸天的 PHP 7 ,你值得拥有
- python安装的模块在pycharm中能用吗_pycharm内无法import已安装的模块问题解决
- Python 基础篇-whl文件怎么安装
- 【Paper】2007_Consensus control for a class of networks of dynamic agents 二阶静态一致性
- 最小二乘拟合,L1、L2正则化约束--转
- java oracle数据备份_Java备份还原Oracle数据库
- 电商三巨头交成绩单,这次拼多多输了吗?
- 如何深入浅出的理解数据仓库建模?
- install ADT plugin
- 7.2图的存储结构(邻接矩阵)
- Android 系统(170)----收到短信,FM外放自动切回耳机
- 微信终于可以隐身了,快看看!
- 用Java获取当前工作目录
- UVA10193 All You Need Is Love【进制+GCD】
- linux中文乱码解决方案
- 烂泥:apache虚拟主机的学习与应用
- android禁止wifi,android – 防止WiFi-direct在不使用时关闭
- 百度知心搜索–基于深度数据瓦解和用户行为分析的搜索引擎
- 使用循环结构输出数字三角形图形
- flash中如何制作播放和暂停按钮(as3.0)
热门文章
- win8.1系统中迅雷看看闪退问题
- Android使用局域网打印机生成打印任务
- 方舟win10自建服务器,win10电脑玩方舟生存进化常见问题汇总
- Altium Designer 的技巧补充
- 机器学习入门——加州房价问题
- oracle查询数字类溢出,有趣的数值溢出(一)
- php不使用第三变量互换,总结PHP不用第三个变量交换两个变量的值的几种方法
- 如何修改anaconda的文件目录_Anaconda安装的常见错误和python的基础知识
- html 制作魔方源代码,CSS3 3d环境实现立体 魔方效果代码
- Drools决策表的使用