涉及到内容的滚动与拖拽,使用UIScrllView。

对于滚动的多张图片,由于超出屏幕,应该使用代码添加代码。

添加的细节是:图片的宽高即为滚动视图的宽高,图片的y=0,x=图片的序号乘以图片的宽度。

为了美观,还应该去掉水平滚动条,代码为:

self.scrollView.showsHorizontalScrollIndicator = NO;

一定不要忘了设定滚动范围:这里仅仅进行水平滚动,因此垂直滚动范围为0,即当前视图宽度。

CGFloat contentW = imageCount * self.imageW;
self.scrollView.contentSize = CGSizeMake(contentW, 0);

这样可以实现多张图片,但是滑动时无法自动停留在一个图片上,而会卡在中间,这需要分页来解决。

self.scrollView.pagingEnabled = YES;

启动分页以后,会自动根据ScrollView的宽度进行分页。

为了用户体验,应该用小圆点来指示总页数和当前位置,这个控件称为Page Control。

但是在动态添加图片时会盖住这个控件,因此可以采用另一个插入方法,指定将视图插入到index=0处(最顶层,也就是最下层)。

[self.scrollView insertSubview:imageView atIndex:0];

另一个细节,为了将Page Control设置在UIScrollView的上层,又要在其上方,直接拖动会使得UIScrollView将其吸收,可以通过直接修改y值来实现拖动。

为了得到当前页码供Page Control切换,应该设置ScrollView的代理,设置代理的另一种方法是在ScrollView上右键拖线到当前根视图View。

Tip:代理方法的命名规范,以类名开头

为了算出页码,可以根据contentOffset方法来判断。

用下面的方法来切换页码即可:页码总数用numberOfPages来设置。

self.pageControl.currentPage = self.scrollView.contentOffset.x / self.imageW;

这样的缺点是如果右边的图片占优势,无法动态的切换页码,为了动态的切换原点,应该在contentOffset基础上加上一半图片宽度,来达到准确修改页码。

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
self.pageControl.currentPage = (self.scrollView.contentOffset.x + self.imageW * 0.5) / self.imageW;
}

但是这样似乎会出现问题,使劲点击小圆点圆点会前进。只需要禁用Page Control的Enable属性即可解决。

实现自动翻页:

要借助定时器,NSTimer或者CADisplayLink,后者适合用来做游戏,可以实现短时间间隔。做事的频率低,用NSTimer。因此这里使用NSTimer。

Tip:schedu...方法不用使用fire可以自动开始。

[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(nextImage) userInfo:nil repeats:YES];

Tip:定时器执行的是target的@selector中的方法。

Tip:ScrollView自带动画。方法有animated参数。

为了自动切换页码,注意的是不要直接修改pageControl的currentPage,因为前面的委托函数会实时检测当前位置,会引起冲突,应该弄一个临时变量来获取和达到下一页,真正的currentPage依然由委托实现。

- (void)nextImage{
//1.增加Page Control的页码
int page = 0;
if (self.pageControl.currentPage == imageCount - 1) {
page = 0;
}else{
page = self.pageControl.currentPage + 1;
}
CGPoint offset = CGPointMake(page * self.imageW, 0);
[self.scrollView setContentOffset:offset animated:YES];
}

问题一:

单线程工作,如果有其他滚动操作,就不能自动翻页了。

问题二:

如果按住页码不让跳,定时器无法跳转,会累计定时器的次数,在松手时一次性跳完。

问题二的解决方法是在用户拽住的时候停止定时器,松手的时候再开启定时器,应该用代理。

Tip:定时器禁用后无法再启用,因此应该重新定义定时器。

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
[self.timer invalidate];
self.timer = nil;
} - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
self.timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(nextImage) userInfo:nil repeats:YES];
}

问题一的解决:

一个程序默认会开一个线程(主线程),处理UI界面和事件。

注意,UI界面的刷新只能交给主线程来做。

因此应该时分复用来处理每个内容。

应该通过获取当前的消息循环(RunLoop),来将定时器的优先级提高。

Tip:在学习一个方法时,如果一个参数不是枚举而是字符串,那么字符串一般是和这个方法在同一个文件中用宏进行定义的,因此可以在上面查到。

提高定时器优先级的方法为:

[[NSRunLoop currentRunLoop ] addTimer:self.timer forMode:NSRunLoopCommonModes];

Tip:以后使用定时器一定要小心,否则容易造成定时器不响应而引发问题。

问题三:如果图片的数量非常的多,那么提前创建这么多ImageView是不明智的。

一种方法是用到的时候再创建(类似TableCell的思路),另一种方法是循环利用这些ImageView。

用三个ImageView就可以实现这种循环。

无限滚动的另一个好处就是最后一张向右拖动到第一张,第一张向左拖动到最后一张。

重点是代理方法(didScroll)。

这种方式适用于大量图片。

(九)UIScrollView和PageControl的分页的更多相关文章

  1. Delphi 停靠技术的应用3(两个窗体停靠成PageControl样式, 分页停靠)

    Delphi 停靠技术的应用3(两个窗体停靠成PageControl样式, 分页停靠) 因为TPageControl组件重载了TWinControl组件的DoAddDockClient和DoRemov ...

  2. 第二百三十九节,Bootstrap路径分页标签和徽章组件

    Bootstrap路径分页标签和徽章组件 学习要点: 1.路径组件 2.分页组件 3.标签组件 4.徽章组件 本节课我们主要学习一下 Bootstrap 的四个组件功能:路径组件.分页组件.标签组件 ...

  3. Elasticsearch教程(九) elasticsearch 查询数据 | 分页查询

    Elasticsearch  的查询很灵活,并且有Filter,有分组功能,还有ScriptFilter等等,所以很强大.下面上代码: 一个简单的查询,返回一个List<对象> ..    ...

  4. IOS 欢迎页(UIScrollView,UIPageControl)

    本文介绍了app欢迎页的简单实现.只有第一次运行程序时才说会出现,其余时间不会出现.下面是效果图. 代码如下:(如有不明白的可以评论我,我会详细讲解) // // ViewController.m / ...

  5. Asp.net+JS 分页

    function pagestart() {//初始化页面,获取公司新闻 $("#pagediv").hide(); $("); var pagesize = $(&qu ...

  6. iOS开发——UI篇Swift篇&UIScrollView

    UIScrollView //返回按钮事件 @IBAction func backButtonClick() { self.navigationController?.popViewControlle ...

  7. [iOS基础控件 - 5.1] UIScrollView

    A.需要掌握 UIScrollView 是一个能够滚动的视图控件,可以用来展示大量内容,如手机的“设置” 1.常见属性 2.常用代理方法 3.缩放 4.UIScrollView和UIPageContr ...

  8. [转]IOS 学习笔记(8) 滚动视图(UIScrollView)的使用方法

    下面介绍pageControl结合ScrollView实现连续滑动翻页的效果,ScrollView我们在应用开发中经常用到,以g这种翻页效果还是很好看的,如下图所示: 通过这个例子,我们重点学习UIS ...

  9. swift开发之 -- 自动轮播图(UIScrollView+UIPageControl+Timer)

    比较简单,原理就不说了,这里只做记录: 代码如下: 1,准备 var pageControl:UIPageControl? var myscrollView:UIScrollView? var myT ...

随机推荐

  1. PHP 实例 - AJAX 实时搜索

    AJAX Live Search 在下面的实例中,我们将演示一个实时的搜索,在您键入数据的同时即可得到搜索结果. 实时的搜索与传统的搜索相比,具有很多优势: 当键入数据时,就会显示出匹配的结果 当继续 ...

  2. Java第9次实验(网络)

    参考资料 本次作业参考文件 正则表达式参考资料 注:主要根据实验任务书的指导完成本次实验. 第1次实验 1. 网络基础 ipconfig.ping telnet(连接BBS与连接Web服务器的不同) ...

  3. Java程序员的现代RPC指南

    Java程序员的现代RPC指南 1.前言 1.1 RPC框架简介 最早接触RPC还是初学Java时,直接用Socket API传东西好麻烦.于是发现了JDK直接支持的RMI,然后就用得不亦乐乎,各种大 ...

  4. C/C++ 函数指针

    函数声明 例如: float func(int, int); 以上就是一个函数的声明,要注意它的实际功能并没有被实现,换句话说就是它并没有被定义,只是声明此函数的存在.要想调用次函数,你必须对对此函数 ...

  5. shell编程--流程控制for,do-while,if-then,break,continue,case等

    2.5 流程控制 2.5.1 if语法 1.语法格式 if condition then     statements [elif condition     then statements. ..] ...

  6. FORM开发之键性弹性域开发

    1.创建表时带有键弹性域字段 SUMMARY_FLAG VARCHAR2(1) , /* 必须有此字段 */ ENABLED_FLAG VARCHAR2(1) , /* 必须有此字段 */ START ...

  7. 【SSH系列】---Hibernate的基本映射

    开篇前言       在前面的博文中,小编分别介绍了[SSH系列]-- hibernate基本原理&&入门demo,通过这篇博文,小伙伴们对hibernate已经有了基本的了解,以及h ...

  8. SQLite 分离数据库(http://www.w3cschool.cc/sqlite/sqlite-detach-database.html)

    SQLite 分离数据库 SQLite的 DETACH DTABASE 语句是用来把命名数据库从一个数据库连接分离和游离出来,连接是之前使用 ATTACH 语句附加的.如果同一个数据库文件已经被附加上 ...

  9. Spark分布式计算和RDD模型研究

    1背景介绍 现今分布式计算框架像MapReduce和Dryad都提供了高层次的原语,使用户不用操心任务分发和错误容忍,非常容易地编写出并行计算程序.然而这些框架都缺乏对分布式内存的抽象和支持,使其在某 ...

  10. 对N各集合中的任意元素进行排列组合问题

    小李去市场买菜,有蔬菜(茄子.黄瓜.大白菜...等k中素菜),和肉类(牛肉,羊肉,鸡肉...等m种荤菜),及点心(麻饼,桃酥,枣花...等n中点心),现在老婆要求每天一荤一素一点心 并且每天的样式要尽 ...