A.概念
例子就是桌面的APP列表,当APP数量超过一个屏幕,自动进行分页
 
B.实现思路
1.创建一个UIScrollView,这里设置为宽度跟屏幕相同,高度1/4屏幕高度左右
2.使用代码在UIScrollView中添加ImageView,横向放入多张ImageView
3.设置UIScrollView的contentSize为所有图片的宽度总和
4.要保证UIScrollView的宽度等于一张ImageView的宽度,才能正确分页
 
C.相关属性
设置属性pageEnable = YES,UIScrollView会被分割成多个独立页面,进行分页显示
一般使用UIPageControl增强效果,UIPageControl常见属性:
  1. // 总页数
  2. @property(nonatomic) NSInteger numberOfPages; // default is 0
  3. // 当前页码
  4. @property(nonatomic) NSInteger currentPage;
  5. // 只有一页的时候隐藏页码
  6. @property(nonatomic) BOOL hidesForSinglePage; // hide the the indicator if there is only one page. default is NO
  7. // 其他页码指示颜色
  8. @property(nonatomic,retain) UIColor *pageIndicatorTintColor;
  9. // 当前页码指示颜色
  10. @property(nonatomic,retain) UIColor *currentPageIndicatorTintColor;
 
 
D.实现步骤
1. 创建一个UIScrollView,设置位置、尺寸
 
2.用代码加载多张图片
  1. CGFloat imageWidth = ;
  2. CGFloat imageHeight = ;
  3. CGFloat imageY = ;
  4.  
  5. for (int i=; i<; i++) {
  6. CGFloat imageX = i * imageWidth;
  7. UIImageView *currentImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:@"img_%02d", i+]]];
  8. currentImageView.frame = CGRectMake(imageX, imageY, imageWidth, imageHeight);
  9.  
  10. [self.scrollView addSubview:currentImageView];
  11. }
 
3.设置contentSize
  1. // 设置可以拖曳的范围,只允许横向拖曳,而且范围是所有的图片宽度总和
  2. self.scrollView.contentSize = CGSizeMake( * imageWidth, );
 
4.开启 pageEnable = YES
     每次拖曳至少滑动1个UIScrollView宽度单位,设置UIScrollView的宽度为图片的宽度之后,刚好翻过一页。
  1. // 开启翻页模式,每次拖曳都会滑动一个UIScrollView宽度单位
  2. self.scrollView.pagingEnabled = YES;
 
没有开启之前,切换两幅图片的时候终止拖曳,会停留在那一刻的显示状态
 
开启之后效果就像书本翻页一样
 
 
5.加入pageControl
pageControl要放在UIScrollView外,而且要比UIScrollView更前,才能正常显示
 
 
6.使用代码设置pageControl
pageControl属性:
  1. // 总页数
  2. @property(nonatomic) NSInteger numberOfPages; // default is 0
  3. // 当前页码
  4. @property(nonatomic) NSInteger currentPage;
  5. // 只有一页的时候隐藏页码
  6. @property(nonatomic) BOOL hidesForSinglePage; // hide the the indicator if there is only one page. default is NO
  7. // 其他页码指示颜色
  8. @property(nonatomic,retain) UIColor *pageIndicatorTintColor;
  9. // 当前页码指示颜色
  10. @property(nonatomic,retain) UIColor *currentPageIndicatorTintColor;
 
(1)要手动设置pageControl,它才能正常工作
  1. // 设置pageControl
  2. self.pageControl.numberOfPages = ;
  3. self.pageControl.pageIndicatorTintColor = [UIColor blackColor];
  4.  
  5. //设置delegate
  6. self.scrollView.delegate = self;
 
(2)控制器遵守UIScrollViewDelegate协议,在 scrollViewDidScroll中动态设置当前页码
  1. /** 当scrollView滚动的时候调用 */
  2. - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
  3. CGFloat scrollWidth = scrollView.frame.size.width;
  4.  
  5. // 当一副图片拖曳超过一半的时候就重新计算页码
  6. int page = (scrollView.contentOffset.x + scrollWidth * 0.5) / scrollWidth;
  7.  
  8. self.pageControl.currentPage = page;
  9. }
 
 
 
7.使用定时器NSTimer自动换页
(1)添加定时器
  1. // 创建定时器
  2. NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval: target:self selector:@selector(nextImage) userInfo:nil repeats:YES];
 
(2)创建定时器调用的方法
  1. - (void) nextImage {
  2. // 1.增加pageControl的页码,这里不能直接操作currentPage,因为这样会和scrollViewDidScroll的页码计算冲突,应该是滚动画面,触发scrollViewDidScroll进行页码转换
  3. int pageNo = ;
  4. if (self.pageControl.currentPage == (IMAGE_COUNT - )) {
  5. pageNo = ;
  6. }
  7. else {
  8. pageNo = self.pageControl.currentPage + ;
  9. }
  10.  
  11. // 2.计算scrollView的滑动位置
  12. CGFloat offsetX = pageNo * self.scrollView.frame.size.width;
  13. CGPoint offset = CGPointMake(offsetX, );
  14.  
  15. // 移动一页,带动画效果
  16. [self.scrollView setContentOffset:offset animated:YES];
  17. }
 
(3)定时器的弱点,在单线程运行时,得不到线程资源的时候,定时器定制运行,事件累积,得到资源之后才一起运行,这里有两种情况:
 
a.手动拖曳阻止了定时器
     解决:销毁定时器,确保资源之后再创建一个
  1. // 开始手动拖曳的时候,销毁定时器
  2. - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
  3. [self.timer invalidate]; // 调用了invalidate之后再不可用了
  4. self.timer = nil;
  5. }
  6.  
  7. // 结束手动拖曳,重新定义定时器
  8. - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
  9. [self addTimer];
  10. }
  11.  
  12. // 添加定时器
  13. - (void) addTimer {
  14. self.timer = [NSTimer scheduledTimerWithTimeInterval: target:self selector:@selector(nextImage) userInfo:nil repeats:YES];
  15. }
 
b.外部可刷新的控件抢占了所有线程资源
如下图中,添加了一个TextView,当拖曳其滚动条时,占用了所有线程刷新资源,定时器就被阻断了
 
解决:争取主线程资源来刷新(分享资源)
  1. // 添加定时器
  2. - (void) addTimer {
  3. self.timer = [NSTimer scheduledTimerWithTimeInterval: target:self selector:@selector(nextImage) userInfo:nil repeats:YES];
  4.  
  5. // 获得主线程资源,防止另外的如可滚动控件的资源全占用
  6. [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
  7. }
 
 
E.滚动页的优化
1.只使用3个ImageView加载图片,动态加载图片
2.无限滚动
 
 
F.主要代码:
  1. //
  2. // ViewController.m
  3. // ScrollViewPage
  4. //
  5. // Created by hellovoidworld on 14/11/28.
  6. // Copyright (c) 2014年 hellovoidworld. All rights reserved.
  7. //
  8.  
  9. #import "ViewController.h"
  10.  
  11. #define IMAGE_COUNT 5
  12.  
  13. @interface ViewController () <UIScrollViewDelegate>
  14. @property (weak, nonatomic) IBOutlet UIScrollView *scrollView; // 滚动控件
  15. @property (weak, nonatomic) IBOutlet UIPageControl *pageControl; // 页码控件
  16.  
  17. @property(nonatomic, strong) NSTimer *timer; // 定时器
  18.  
  19. @end
  20.  
  21. @implementation ViewController
  22.  
  23. - (void)viewDidLoad {
  24. [super viewDidLoad];
  25. // Do any additional setup after loading the view, typically from a nib.
  26.  
  27. CGFloat imageWidth = ;
  28. CGFloat imageHeight = ;
  29. CGFloat imageY = ;
  30.  
  31. for (int i=; i<IMAGE_COUNT; i++) {
  32. CGFloat imageX = i * imageWidth;
  33. UIImageView *currentImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:@"img_%02d", i+]]];
  34. currentImageView.frame = CGRectMake(imageX, imageY, imageWidth, imageHeight);
  35.  
  36. [self.scrollView addSubview:currentImageView];
  37. }
  38.  
  39. // 设置可以拖曳的范围,只允许横向拖曳,而且范围是所有的图片宽度总和
  40. self.scrollView.contentSize = CGSizeMake(IMAGE_COUNT * imageWidth, );
  41.  
  42. // 开启翻页模式,每次拖曳都会滑动一个UIScrollView宽度单位
  43. self.scrollView.pagingEnabled = YES;
  44.  
  45. // 设置pageControl
  46. self.pageControl.numberOfPages = ;
  47. self.pageControl.pageIndicatorTintColor = [UIColor blackColor];
  48. self.pageControl.currentPageIndicatorTintColor = [UIColor redColor];
  49.  
  50. // 设置delegate
  51. self.scrollView.delegate = self;
  52.  
  53. // 创建定时器
  54. [self addTimer];
  55. }
  56.  
  57. - (void)didReceiveMemoryWarning {
  58. [super didReceiveMemoryWarning];
  59. // Dispose of any resources that can be recreated.
  60. }
  61.  
  62. /** 当scrollView滚动的时候调用 */
  63. - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
  64. CGFloat scrollWidth = scrollView.frame.size.width;
  65.  
  66. // 当一副图片拖曳超过一半的时候就重新计算页码
  67. int page = (scrollView.contentOffset.x + scrollWidth * 0.5) / scrollWidth;
  68.  
  69. self.pageControl.currentPage = page;
  70. }
  71.  
  72. - (void) nextImage {
  73. // 1.增加pageControl的页码,这里不能直接操作currentPage,因为这样会和scrollViewDidScroll的页码计算冲突,应该是滚动画面,触发scrollViewDidScroll进行页码转换
  74. int pageNo = ;
  75. if (self.pageControl.currentPage == (IMAGE_COUNT - )) {
  76. pageNo = ;
  77. }
  78. else {
  79. pageNo = self.pageControl.currentPage + ;
  80. }
  81.  
  82. // 2.计算scrollView的滑动位置
  83. CGFloat offsetX = pageNo * self.scrollView.frame.size.width;
  84. CGPoint offset = CGPointMake(offsetX, );
  85.  
  86. // 移动一页,带动画效果
  87. [self.scrollView setContentOffset:offset animated:YES];
  88. }
  89.  
  90. // 开始手动拖曳的时候,销毁定时器
  91. - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
  92. [self.timer invalidate]; // 调用了invalidate之后再不可用了
  93. self.timer = nil;
  94. }
  95.  
  96. // 结束手动拖曳,重新定义定时器
  97. - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
  98. [self addTimer];
  99. }
  100.  
  101. // 添加定时器
  102. - (void) addTimer {
  103. self.timer = [NSTimer scheduledTimerWithTimeInterval: target:self selector:@selector(nextImage) userInfo:nil repeats:YES];
  104.  
  105. // 获得主线程资源,防止另外的如可滚动控件的资源全占用
  106. [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
  107. }
  108.  
  109. @end
 

[iOS基础控件 - 5.4] 广告分页代码(UIScrollView制作)的更多相关文章

  1. [iOS基础控件 - 5.5] 代理设计模式 (基于”APP列表"练习)

    A.概述      在"[iOS基础控件 - 4.4] APP列表 进一步封装,初见MVC模式”上进一步改进,给“下载”按钮加上效果.功能      1.按钮点击后,显示为“已下载”,并且不 ...

  2. [iOS基础控件 - 6.6.1] 展示团购数据代码

      1.主控制器: // // ViewController.m // GroupPurchase // // Created by hellovoidworld on 14/12/3. // Cop ...

  3. iOS 基础控件(下)

    上篇介绍了UIButton.UILabel.UIImageView和UITextField,这篇就简短一点介绍UIScrollView和UIAlertView. UIScrollView 顾名思义也知 ...

  4. [iOS基础控件 - 7.0] UIWebView

    A.基本使用 1.概念 iOS内置的浏览器控件 Safari浏览器就是通过UIWebView实现的   2.用途:制作简易浏览器 (1)基本请求 创建请求 加载请求 (2)代理监听webView加载, ...

  5. [iOS基础控件 - 6.11.3] 私人通讯录Demo 控制器的数据传递、存储

    A.需求 1.搭建一个"私人通讯录"Demo 2.模拟登陆界面 账号 密码 记住密码开关 自动登陆开关 登陆按钮 3.退出注销 4.增删改查 5.恢复数据(取消修改)   这个代码 ...

  6. [iOS基础控件 - 6.10.2] PickerView 自定义row内容 国家选择Demo

    A.需求 1.自定义一个UIView和xib,包含国家名和国旗显示 2.学习row的重用   B.实现步骤 1.准备plist文件和国旗图片     2.创建模型 // // Flag.h // Co ...

  7. [iOS基础控件 - 6.9] 聊天界面Demo

    A.需求 做出一个类似于QQ.微信的聊天界面 1.每个cell包含发送时间.发送人(头像).发送信息 2.使用对方头像放在左边,我方头像在右边 3.对方信息使用白色背景对话框,我方信息使用蓝色背景对话 ...

  8. [iOS基础控件 - 6.7] 微博展示 使用代码自定义TableCell(动态尺寸)

    A.需求 1.类似于微博内容的展示 2.头像 3.名字 4.会员标志 5.内容 6.分割线 7.配图(可选,可有可无)   code source: https://github.com/hellov ...

  9. [iOS基础控件 - 6.6] 展示团购数据 自定义TableViewCell

    A.需求 1.头部广告 2.自定义cell:含有图片.名称.购买数量.价格 3.使用xib设计自定义cell,自定义cell继承自UITableViewCell 4.尾部“加载更多按钮”,以及其被点击 ...

随机推荐

  1. Mac OS X 启用 Web 服务器

    转载: http://note.rpsh.net/posts/2013/11/26/osx-apache-server-php-mysql/

  2. Android:自定义适配器

    无论是ArrayAdapter还是SimpleAdapter都继承了BaseAdapter,自定义适配器同样继承BaseAdapter 实例:Gallery实现图片浏览器 <?xml versi ...

  3. POJ 1036 Rails 模拟堆栈

    水题,主要是思路清晰,判断明确. 记x为A站最前方的车,y表示下一列要进入B站的车厢,初识时,x=1;y=a1;C=[]; 在调度过程中: if(y==0)那么调度成功,退出模拟过程:否则 if(x= ...

  4. swap chain- IDirect3DSwapChain9

    交换链,对应的接口是IDirect3DSwapChain9,是整个Directx 3D中最核心的接口.D3d程序至少包含一个swap chain,在调用CreateDevice时自动创建, 其中的D3 ...

  5. Eclipse反编译工具Jad及插件JadClipse配置(转)

    Eclipse反编译工具Jad及插件JadClipse配置 Jad是一个Java的一个反编译工具,是用命令行执行,和通常JDK自带的java,javac命令是一样的.不过因为是控制台运行,所以用起来不 ...

  6. Flex 选项卡加载方式简介

    Flex中选项卡默认只加载选中的选项,所以在初始化的时候给其他的选项卡中的对象赋值或是其他操作,都会出现空对象错误. 解决办法:给选项卡设置属性 creationPolicy=”all” 如:< ...

  7. JAVA并行框架学习之ForkJoin

    当硬件处理能力不能按照摩尔定律垂直发展的时候,选择了水平发展,多核处理器已经广泛应用.未来随着技术的进一步发展,可能出现成百上千个处理核心,但现有的程序运行在多核心处理器上并不能得到较大性能的提升,主 ...

  8. C#字符串与char数组互转!

    字符串转换成Char数组string str="abcdefghijklmnopqretuvwxyz";char[] chars=str.ToCharArray(); char数组 ...

  9. POJ 1637 Sightseeing tour ★混合图欧拉回路

    [题目大意]混合图欧拉回路(1 <= N <= 200, 1 <= M <= 1000) [建模方法] 把该图的无向边随便定向,计算每个点的入度和出度.如果有某个点出入度之差为 ...

  10. C# 中的枚举类型 enum (属于值类型)

    原文 C# 中的枚举类型 enum (属于值类型) C# 支持两种特殊的值类型:枚举和结构. 声明枚举:声明时要声明所有可能的值. using System; using System.Collect ...