Swift(二十)UIScrollView

作者: YvanLiu | 来源:发表于2017-08-31 11:46 被阅读621次

更新: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的时候会像弹簧一样有一个碰撞效果。
  • showsHorizontalScrollIndicatorshowsVerticalScrollIndicator的作用是滑动的时候由一个滑块伴随滑动。
  • minimumZoomScalemaximumZoomScale的作用是设置缩放比例,要配合代理方法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时,不调用该方法
    }
}

相关文章

网友评论

    本文标题:Swift(二十)UIScrollView

    本文链接:https://www.haomeiwen.com/subject/yomodxtx.html