更新:2018.05.24
整理了一下demo:SwiftDemo
一个复杂的APP中,往往会包含多个页面,而移动设备的屏幕大小是有限的,因此直接展示在用户眼前的内容也极其有限,但需要展示的内容过多超出一个屏幕的范围时,用户可以通过滚动手势来查看屏幕之外的内容。
- UIScrollView 是一个能够滚动的视图控件,可以展示大量的内容,它直接继承自UIView。
- 可以通过在UIScrollView上滑动手指,查看多个视图控制器中的内容。
1、创建UIScrollView
let scrollView = UIScrollView(frame: view.bounds)
view.addSubview(scrollView)
// 设置是否翻页
scrollView.isPagingEnabled = true
// 可以滚动的区域
scrollView.contentSize = CGSize(width: screenWidth*9, height: screenHeight)
// 显⽰示⽔水平滚动条
scrollView.showsHorizontalScrollIndicator = true
// 显⽰示垂直滚动条
scrollView.showsVerticalScrollIndicator = true
// 滚动条样式
scrollView.indicatorStyle = UIScrollViewIndicatorStyle.white
// 设置回弹效果
scrollView.bounces = true
// 设置scrollView可以滚动
scrollView.isScrollEnabled = true
// 当scrollsToTop=true时,点击设备状态栏会自动滚动到顶部
scrollView.scrollsToTop = true
// 缩放的最小比例
scrollView.minimumZoomScale = 0.5
// 放大的最大比例
scrollView.maximumZoomScale = 2.0
// 缩放回弹
scrollView.bouncesZoom = true
- 我们创建了一个和视图控制器同样大小的scrollView,然后添加到视图上。
- isPagingEnabled属性的作用是设置翻页功能,当设置为true时,滑动的感觉会像翻书一样。
- contentSize是设置scrollView的滚动区域,scrollView只在设置好的区域内滚动。
- bounces属性的作用是设置回弹效果,当热值为false时,滑动到边界之后,scrollview不会再滑动,而设置为true的时候会像弹簧一样有一个碰撞效果。
- showsHorizontalScrollIndicator和showsVerticalScrollIndicator的作用是滑动的时候由一个滑块伴随滑动。
-
minimumZoomScale和maximumZoomScale的作用是设置缩放比例,要配合代理方法
viewForZooming(in scrollView: UIScrollView)
使用。
2. 为UIScrollView添加内容
我这里是找了一组图片,通过for循环添加进去

for i in 1..<10 {
let imageView = UIImageView(frame: CGRect(x: screenWidth*CGFloat(i-1), y: 0, width: screenWidth, height: screenHeight))
imageView.image = UIImage(named: "美女0\(i).jpg")
scrollView.addSubview(imageView)
}
- 通过for循环创建了9个UIImageView并添加图片。
3. UIScrollViewDelegate

scrollView.delegate = self
func scrollViewDidScroll(_ scrollView: UIScrollView) {
print("scrollView滚动时调用,只要offset的值发生变化就调用")
}
func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) {
print("当将要开始缩放时,执行该方法。一次有效缩放就只执行一次。")
}
func scrollViewDidZoom(_ scrollView: UIScrollView) {
print("当scrollView缩放时,调用该方法。在缩放过程中,会多次调用")
}
func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) {
print("当缩放结束后,并且缩放大小回到minimumZoomScale与maximumZoomScale之间后(我们也许会超出缩放范围),调用该方法。")
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
print("返回将要缩放的UIView对象。要执行多次")
return scrollView.subviews.first
}
func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool {
print("指示当用户点击状态栏后,滚动视图是否能够滚动到顶部。")// 需要设置滚动视图的属性:scrollView.scrollsToTop=true
return true
}
func scrollViewDidScrollToTop(_ scrollView: UIScrollView) {
print("当滚动视图滚动到最顶端后,执行该方法")
}
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
print("当开始滚动视图时,执行该方法。一次有效滑动只执行一次。")
}
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
print("滑动视图,当手指离开屏幕那一霎那,调用该方法。一次有效滑动只执行一次。")
}
func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
print("滑动减速时调用该方法。")
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
print("滚动视图减速完成,滚动将停止时,调用该方法。一次有效滑动只执行一次。")
}
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
print("当滚动视图动画完成后,调用该方法,如果没有动画,那么该方法将不被调用")
}
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
print("滑动scrollView,并且手指离开时执行。一次有效滑动只执行一次。") //当pagingEnabled属性为true时,不调用该方法
}

- 就不一一解释了,方法里都有输出,如果有不理解的自己跑一下,
- viewForZooming return的返回值是我测试缩放效果添加的。只添加了第一张图的缩放,如果需要可以具体实现一下。
4. UIPageControl

- 这里对之前的代码有一些修改,首先定义了一个页码控制对象pageControl,然后把scrollView的实例化提到上面来,目的是使其在整个SecondViewController中都可以使用。
// 页码控制器
pageControl.frame = CGRect(x: 0, y: screenHeight-50, width: screenWidth, height: 50)
pageControl.backgroundColor = UIColor.gray
// 总共有多少页
pageControl.numberOfPages = 9
// 当前页码
pageControl.currentPage = 0
// 添加点击事件
pageControl.addTarget(self, action: #selector(pageControlClick), for: .valueChanged)
view.addSubview(pageControl)
- 设置页面控制器的属性,总页码和当前页码,并添加点击方法。
func pageControlClick(pageControl:UIPageControl) {
UIView.animate(withDuration: 0.3) {
self.scrollView.contentOffset = CGPoint(x: CGFloat(pageControl.currentPage)*self.scrollView.frame.size.width, y: 0)
}
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
print("scrollView滚动时调用,只要offset的值发生变化就调用")
// 函数floor的作用是返回比小的整数,比如floor(1.2312) = 1
let page = floor((scrollView.contentOffset.x)/scrollView.frame.size.width)
pageControl.currentPage = Int(page)
}

- 第一个方法是页面控制器的值发生变化调用的方法,注意,点击白点没有任何效果,我是试过了,但点击两边的空白位置却可以调起
pageControlClick
方法。 - 第二个是UIScrollView的代理方法,实时调用,只要offset的值发生变化,它就调用,floor函数的作用是返回比小的整数,比如floor(1.2312) = 1。
- 实现这两个方法,第一个的作用是点击空区域从而实现翻页,第二个的作用是当翻页的时候,动态计算页码,控制白点位置。
5. 整篇代码
import UIKit
class SecondViewController: UIViewController,UIScrollViewDelegate {
let pageControl = UIPageControl()
let scrollView = UIScrollView()
override func viewDidLoad() {
super.viewDidLoad()
title = "第二页"
view.backgroundColor = UIColor.cyan
let screenWidth = UIScreen.main.bounds.width
let screenHeight = UIScreen.main.bounds.height
scrollView.frame = view.bounds
view.addSubview(scrollView)
// 设置是否翻页
scrollView.isPagingEnabled = true
// 可以滚动的区域
scrollView.contentSize = CGSize(width: screenWidth*9, height: screenHeight)
// 显⽰示⽔水平滚动条
scrollView.showsHorizontalScrollIndicator = true
// 显⽰示垂直滚动条
scrollView.showsVerticalScrollIndicator = true
// 滚动条样式
scrollView.indicatorStyle = UIScrollViewIndicatorStyle.white
// 设置回弹效果
scrollView.bounces = true
// 设置scrollView可以滚动
scrollView.isScrollEnabled = true
// 当scrollsToTop=true时,点击设备状态栏会自动滚动到顶部
scrollView.scrollsToTop = true
// 缩放的最小比例
scrollView.minimumZoomScale = 0.5
// 放大的最大比例
scrollView.maximumZoomScale = 2.0
// 缩放回弹
scrollView.bouncesZoom = true
// 代理
scrollView.delegate = self
for i in 1..<10 {
let imageView = UIImageView(frame: CGRect(x: screenWidth*CGFloat(i-1), y: 0, width: screenWidth, height: screenHeight))
imageView.image = UIImage(named: "美女0\(i).jpg")
scrollView.addSubview(imageView)
}
// 页码控制器
pageControl.frame = CGRect(x: 0, y: screenHeight-50, width: screenWidth, height: 50)
pageControl.backgroundColor = UIColor.gray
// 总共有多少页
pageControl.numberOfPages = 9
// 当前页码
pageControl.currentPage = 0
// 添加点击事件
pageControl.addTarget(self, action: #selector(pageControlClick), for: .valueChanged)
view.addSubview(pageControl)
}
//MARK: pageControl点击调用方法
func pageControlClick(pageControl:UIPageControl) {
UIView.animate(withDuration: 0.3) {
self.scrollView.contentOffset = CGPoint(x: CGFloat(pageControl.currentPage)*self.scrollView.frame.size.width, y: 0)
}
}
//MARK: UIScrollViewDelegate
func scrollViewDidScroll(_ scrollView: UIScrollView) {
print("scrollView滚动时调用,只要offset的值发生变化就调用")
// 函数floor的作用是返回比小的整数,比如floor(1.2312) = 1
let page = floor((scrollView.contentOffset.x)/scrollView.frame.size.width)
pageControl.currentPage = Int(page)
}
func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) {
print("当将要开始缩放时,执行该方法。一次有效缩放就只执行一次。")
}
func scrollViewDidZoom(_ scrollView: UIScrollView) {
print("当scrollView缩放时,调用该方法。在缩放过程中,会多次调用")
}
func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) {
print("当缩放结束后,并且缩放大小回到minimumZoomScale与maximumZoomScale之间后(我们也许会超出缩放范围),调用该方法。")
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
print("返回将要缩放的UIView对象。要执行多次")
return scrollView.subviews.first
}
func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool {
print("指示当用户点击状态栏后,滚动视图是否能够滚动到顶部。")// 需要设置滚动视图的属性:scrollView.scrollsToTop=true
return true
}
func scrollViewDidScrollToTop(_ scrollView: UIScrollView) {
print("当滚动视图滚动到最顶端后,执行该方法")
}
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
print("当开始滚动视图时,执行该方法。一次有效滑动只执行一次。")
}
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
print("滑动视图,当手指离开屏幕那一霎那,调用该方法。一次有效滑动只执行一次。")
}
func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
print("滑动减速时调用该方法。")
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
print("滚动视图减速完成,滚动将停止时,调用该方法。一次有效滑动只执行一次。")
}
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
print("当滚动视图动画完成后,调用该方法,如果没有动画,那么该方法将不被调用")
}
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
print("滑动scrollView,并且手指离开时执行。一次有效滑动只执行一次。") //当pagingEnabled属性为true时,不调用该方法
}
}
网友评论