如今非常多应用里面多多少少都用到了循环滚动,要么是图片、要么是view,或者是其它,我总结一下,写了个demo分享给大家。

先看代码之后在讲原理:

1.创建一个空的项目(这个我就不多说了)。

2.加入一个ViewController。

3.在appdelegate加入:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; ViewController *vc = [[ViewController alloc] init];
self.window.rootViewController = vc; self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}

4.看看ViewController.m里面的文件:

<span style="font-size:14px;">#import "ViewController.h"

@interface ViewController ()<UIScrollViewDelegate>

@property (nonatomic, strong) UIScrollView *readCannelScrollView;
@property (nonatomic, strong) UILabel *pageOneView;
@property (nonatomic, strong) UILabel *pageTwoView;
@property (nonatomic, strong) UILabel *pageThreeView; @end @implementation ViewController - (void)dealloc
{
_readCannelScrollView = nil;
_pageOneView = nil;
_pageTwoView = nil;
_pageThreeView = nil;
} - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
} - (void)viewDidLoad
{
[super viewDidLoad]; //容器的属性设置
self.readCannelScrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:self.readCannelScrollView];
CGSize size = self.readCannelScrollView.contentSize;
size.width = 320*3;
self.readCannelScrollView.contentSize = size;
self.readCannelScrollView.pagingEnabled = YES;
self.readCannelScrollView.showsHorizontalScrollIndicator = NO;
self.readCannelScrollView.delegate = self;
self.readCannelScrollView.contentOffset = CGPointMake(0, 0);
//end //加入页面1
self.pageOneView = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, self.view.bounds.size.height)];
self.pageOneView.backgroundColor = [UIColor lightGrayColor];
self.pageOneView.text = @"1";
self.pageOneView.font = [UIFont systemFontOfSize:80];
self.pageOneView.textAlignment = NSTextAlignmentCenter;
[self.readCannelScrollView addSubview:self.pageOneView]; //加入页面2
self.pageTwoView = [[UILabel alloc] initWithFrame:CGRectMake(320, 0, 320, self.view.bounds.size.height)];
self.pageTwoView.backgroundColor = [UIColor greenColor];
self.pageTwoView.text = @"2";
self.pageTwoView.font = [UIFont systemFontOfSize:80];
self.pageTwoView.textAlignment = NSTextAlignmentCenter;
[self.readCannelScrollView addSubview:self.pageTwoView]; //加入页面3
self.pageThreeView = [[UILabel alloc] initWithFrame:CGRectMake(640, 0, 320, self.view.bounds.size.height)];
self.pageThreeView.backgroundColor = [UIColor grayColor];
self.pageThreeView.text = @"3";
self.pageThreeView.font = [UIFont systemFontOfSize:80];
self.pageThreeView.textAlignment = NSTextAlignmentCenter;
[self.readCannelScrollView addSubview:self.pageThreeView];
} - (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
} #pragma mark -
#pragma mark - scroll delegate
<span style="color:#996633;">- (void) scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
NSLog(@"scrollView.contentOffset.x=%f",scrollView.contentOffset.x);
CGFloat pageWidth = scrollView.frame.size.width;
int currentPage = floor((scrollView.contentOffset.x-pageWidth/2)/pageWidth)+1; if (currentPage == 0)
{
UILabel *tmpTxtView = self.pageThreeView;
self.pageThreeView = self.pageTwoView;
self.pageTwoView = self.pageOneView;
self.pageOneView = tmpTxtView;
} if (currentPage == 2)
{
//换指针
UILabel *tmpTxtView = self.pageOneView;
self.pageOneView = self.pageTwoView;
self.pageTwoView = self.pageThreeView;
self.pageThreeView = tmpTxtView;
} //恢复原位
self.pageOneView.frame = (CGRect){0,0,self.pageOneView.frame.size};
self.pageTwoView.frame = (CGRect){320,0,self.pageTwoView.frame.size};
self.pageThreeView.frame = (CGRect){640,0,self.pageThreeView.frame.size};
self.readCannelScrollView.contentOffset = CGPointMake(320, 0); } @end</span>

5.原理说明,小伙伴我们一起想一下。怎样让一个scrollview实现循环滚动。看下图:

a.用三个View进行循环滚动,上图P1、P2、P3(程序中的pageOneView、pageTwoView、pageThreeView)

b.(開始执行除外。那是的contentoffset.x = 0)始终让P2在中间是实现循环滚动的关键。

c.P2此时在中间(如上图)即contentoffset.x = 320。此时再向左滑动。P3在中间页面,即contentoffset.x = 640。

d.这时候,肯定会想,是不是把P1移动到TEMP0的位置。小伙伴你真聪明。可是为了写成一个通用方法,光是移动位置是不正确的,那能不能保证P1、P2、P3这个顺序永远不变,答案是YES。

e.1>永远保持P1、P2、P3顺序。同一时候。位置(frame)也要同样  2>让P2用于居中。

f.满足e中两条,怎样做到:首先e的第一条看上图,滑动后的界面最右边有个红色虚拟的框框。假设假设(实际上没有移动)我把P1放到那个位置,顺序就是P2\P3\P1(TEMP0),为了保证顺序,我须要交换指针。可是假设我直接把指针P1=P2。在运行P3=P1时候。会有问题的。你懂的。在进行换值的时候须要借助暂时指针变量的。

g.指针换完了,可是位置没有变contentoffset.x = 640,我们须要scrollView.contentoffset.x = 320。

h.上述是想左滑动。向右滑动,即是同理。

6.程序分析说明:

<span style="font-size:14px;">CGFloat pageWidth = scrollView.frame.size.width;
int currentPage = floor((scrollView.contentOffset.x-pageWidth/2)/pageWidth)+1;</span>

floor计算 的出来是0、1、2,能够利用是0还是2进行推断用户是向左滑动,还是向右滑动。从而实现循环滚动,后台在配合数组的使用。就能够实现图片等循环滚动啦!

点击下载源码

UIScrollView 循环滚动,代码超简单的更多相关文章

  1. APP中常见上下循环滚动通知的简单实现,点击可进入详情

    APP中常见上下循环滚动通知的简单实现,点击可进入详情 关注finddreams博客,一起分享一起进步!http://blog.csdn.net/finddreams/article/details/ ...

  2. UIScrollView循环滚动1

    现在基本每一个商业APP都会有循环滚动视图,放一些轮播广告之类的,都是放在UIScrollView之上.假如我要实现N张图片的轮播,我借鉴了几个博文,得到两种方法实现: [第一种]:如下图(图片来源于 ...

  3. NGUI实现的一套不同大小 Item 的循环滚动代码

    测试: 数据 & Item  的 Ctrl : using UnityEngine; public class ScrollViewItemData { public int index; p ...

  4. 实现图片的循环滚动——JS的简单应用

    首先默认都了解JS的循环分支运算符等基本语法 用CSS实现简单的布局也是会的. 然后我们就可以来了解一下 [DOM 树节点] 它分为三大类:元素节点.文本节点.属性节点 文本节点跟属性节点为元素节点的 ...

  5. iOS之UIScrollView循环滚动

    #import "ViewController.h" #define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width #d ...

  6. javaWeb实现验证码--代码超简单

    1.前端显示 HTML: <h3>验证码:</h3> <input type="text" name="validationCode&quo ...

  7. 用Python写一个随机数字生成代码,5行代码超简单

    本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 第一步,安装 random 库 random库是使用随机数的Python标准库 ...

  8. jQuery倒计时代码(超简单)

    <!DOCTYPE html> <html lang="en"> <head>   <meta charset="UTF-8&q ...

  9. JavaScript学习笔记——简单无缝循环滚动展示图片的实现

    今天做了一个简单的无缝循环滚动的实例,这种实例在网页中其实还挺常见的,下面分享一下我的学习收获. 首先,无缝滚动的第一个重点就是——动.关于怎么让页面的元素节点动起来,这就得学明白关于JavaScri ...

随机推荐

  1. Android:Date、String、Long三种日期类型之间的相互转换

    源地址:http://blog.csdn.net/wangyanguiyiyang date类型转换为String类型: // formatType格式为yyyy-MM-dd HH:mm:ss//yy ...

  2. redisson实现基于业务的互斥锁

    虽然数据库有锁的实现,但是有时候对于数据的操作更需要业务层控制. 这个解决的问题有次面试被问到过,当时不知道怎么解决,乱说一通,今天也算是有个解决方案了 项目中有个需求,就是订单需要经过一层一层的审核 ...

  3. Codeforces Round #346 (Div. 2) A. Round House 水题

    A. Round House 题目连接: http://www.codeforces.com/contest/659/problem/A Description Vasya lives in a ro ...

  4. MySQL主库切换那些事

    最近连续经历了机架掉电和交换机挂掉,着实切了不少主库,虽然过程心惊胆跳,但是也算是上过战场,经过了实战演习,相信TEAM中的小伙伴们对于切主库已经可以驾轻就熟了. MySQL的主库切换也属于DBA的一 ...

  5. kafka_2.11-0.8.2.1单机版安装

    1.下载kafka安装包wget http://mirrors.cnnic.cn/apache/kafka/0.8.2.1/kafka_2.11-0.8.2.1.tgz 2.复制到安装目录cp kaf ...

  6. oc/object-c/ios用int还是NSInteger

    当需要使用int类型的变量的时候,可以像写C的程序一样,用int,也可以用NSInteger,但更推荐使用NSInteger,因为这样就不用考虑设备是32位的还是64位的. 可以看如下定义:#if _ ...

  7. MYSQL 名人博客

    : DavidYang的博客 - CSDN.NET DimitriK's (dim) Weblog Xaprb · Stay Curious! 飞鸿无痕的博客 - ChinaUnix博客 何登成的技术 ...

  8. 无线AP和无线路由器区别wifi热点

    转自:http://network.51cto.com/art/201310/413327.htm 就像很多用户很容易混淆无线上网卡和无线网卡一样,很多用户也分不清无线AP和无线路由,小峰便是其中的一 ...

  9. 《C++反汇编与逆向分析技术揭秘》之十——析构函数

    局部对象 当对象所在作用域结束之后,销毁栈空间,此时析构函数被调用. 举例: 函数返回时自动调用析构函数: 堆对象 调用析构代理函数来处理析构函数: 为什么使用析构代理函数来调用析构函数?考虑到如果d ...

  10. ffmpeg中的sws_scale算法性能对比

    sws_scale的算法有如下这些选择. #define SWS_FAST_BILINEAR 1#define SWS_BILINEAR 2#define SWS_BICUBIC 4#define S ...