最简单粗暴的方式实现无限循环滚动的UIScrollView

//
//  ViewController.swift
//  UIScrollView_Example
//
//  Created by xxx on 16/4/1.
//  Copyright © 2016年 xxx. All rights reserved.
//

import UIKit

class ViewController: UIViewController, UIScrollViewDelegate {
    
    var scrollView: UIScrollView!
    var childCacheView:[UIView]!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        setupView()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    func setupView() {
        
        childCacheView = []
        
        let frame = CGRectMake(0, 0, self.view.frame.size.width, 400)
        let scrollView = UIScrollView(frame: frame)
        scrollView.delegate = self
        self.view.addSubview(scrollView)
        
        self.scrollView = scrollView
        
        var offset_x: CGFloat = 0.0
        let indexs = [totalCount-1, 0, 1]
        for i in 0 ..< 3 {
            let childView = createChildView(indexs[i])
            childView.frame = CGRectMake(0.0 + offset_x, 0, self.view.frame.size.width, 400)
            scrollView.addSubview(childView)
            offset_x += CGFloat(self.view.frame.size.width)
            
            childView.tag = indexs[i]
            childCacheView.append(childView)
        }
        
        scrollView.contentSize = CGSizeMake(self.view.frame.size.width * 3.0, 400)
        scrollView.pagingEnabled = true
        scrollView.showsVerticalScrollIndicator = false
        scrollView.showsHorizontalScrollIndicator = false
        
        scrollView.setContentOffset(CGPointMake(width, 0), animated: false)
        
        let left = UIButton(frame: CGRectMake(0, 410, 100, 40))
        left.setTitle("Left", forState: UIControlState.Normal)
        left.setTitleColor(UIColor.blackColor(), forState: UIControlState.Normal)
        left.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(ViewController.tapLeftButton(_:))))
        self.view.addSubview(left)
        
        let right = UIButton(frame: CGRectMake(200, 410, 100, 40))
        right.setTitle("Right", forState: UIControlState.Normal)
        right.setTitleColor(UIColor.blackColor(), forState: UIControlState.Normal)
        right.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(ViewController.tapRightButton(_:))))
        self.view.addSubview(right)
        
        
    }
    
    var CGFloat {
        return self.view.frame.size.width
    }
    
    func prevChildView() -> UIView {
        return childCacheView[0]
    }
    
    func currChildView() -> UIView {
        return childCacheView[1]
    }
    
    func nextChildView() -> UIView {
        return childCacheView[2]
    }
    
    var totalCount = 8
    var currentIndex: Int = 0
    
    var urls = [
        "http://pic3.zhongsou.com/image/3807f47d76cc2876255.jpg",
        "http://d.hiphotos.baidu.com/zhidao/pic/item/902397dda144ad3452a5d2fad2a20cf431ad85b0.jpg",
        "http://photo.niaolei.org.cn/uploads/201212/1356349545RuOuHkAy.jpg",
        "http://img3.fengniao.com/forum/attachpics/155/160/6191982.jpg",
        "http://img0.pconline.com.cn/pconline/1403/03/4374256_05_thumb.jpg",
        "http://photo.niaolei.org.cn/uploads/201212/1356350324Tg2Ii27r.jpg",
        "http://images3.qianyan.biz/qy/1/20/89/201472417401165442030.jpg",
        "http://pic3.zhongsou.com/image/380bccf5f1d656ba95e.jpg"
    ]
    
    @objc private func tapImage(gesture: UIGestureRecognizer) {
        print("tapImage...")
    }
    
    @objc private func tapLeftButton(gesture: UIGestureRecognizer) {
        print("tapLeftButton...")
        
        var offset = scrollView.contentOffset
        offset.x -= width
        scrollView.setContentOffset(offset, animated: true)
    }
    
    @objc private func tapRightButton(gesture: UIGestureRecognizer) {
        print("tapRightButton...")
        
        var offset = scrollView.contentOffset
        offset.x += width
        scrollView.setContentOffset(offset, animated: true)
    }
    
    func scrollViewDidScroll(scrollView: UIScrollView) {
        print("scrollViewDidScroll...(scrollView.contentOffset)")
    }
    
    func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
        print("scrollViewDidEndDecelerating...(scrollView.contentOffset)")
        
        computeScrollOffset()
    }
    
    func scrollViewWillBeginDragging(scrollView: UIScrollView) {
        print("scrollViewWillBeginDragging...(scrollView.contentOffset)")
    }
    
    func scrollViewWillBeginDecelerating(scrollView: UIScrollView) {
        print("scrollViewWillBeginDecelerating...(scrollView.contentOffset)")
    }
    
    func scrollViewDidEndScrollingAnimation(scrollView: UIScrollView) {
        print("scrollViewDidEndScrollingAnimation...(scrollView.contentOffset)")
        computeScrollOffset()
    }
    
    func computeScrollOffset() {
        let offset_x = scrollView.contentOffset.x
        let index = offset_x/width
        if index == 0 {
            // 向前滑动
            print("向前滑动")
            
            let currView = currChildView()
            let nextView = nextChildView()
            let prevView = prevChildView()
            
            currChildView().frame.origin.x += width
            prevChildView().frame.origin.x += width
            nextChildView().frame.origin.x -= width * 2.0
            
            scrollView.setContentOffset(CGPointMake(width, 0), animated: false)
            
            childCacheView[0] = nextView
            childCacheView[1] = prevView
            childCacheView[2] = currView
            
            updateChildView(childCacheView[0], currIndex: childCacheView[1].tag, increaseIndex: false)
            
        } else if index == 2 {
            // 向后滑动
            print("向后滑动")
            
            let currView = currChildView()
            let nextView = nextChildView()
            let prevView = prevChildView()
            
            currChildView().frame.origin.x -= width
            nextChildView().frame.origin.x -= width
            prevChildView().frame.origin.x += width * 2.0
            
            scrollView.setContentOffset(CGPointMake(width, 0), animated: false)
            
            childCacheView[0] = currView
            childCacheView[1] = nextView
            childCacheView[2] = prevView
            
            updateChildView(childCacheView[2], currIndex: childCacheView[1].tag, increaseIndex: true)
        }
    }

    func createChildView(index: Int) -> UIView {
        let imageView = UIImageView()
        imageView.userInteractionEnabled = true
        imageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(ViewController.tapImage(_:))))
        
        let label = UILabel(frame: CGRectMake(0, 0, 100, 100))
        label.text = "Label:(index)"
        label.tag = 100
        label.font = UIFont.systemFontOfSize(28.0)
        label.textColor = UIColor.whiteColor()
        imageView.addSubview(label)
        
        imageView.kf_setImageWithURL(NSURL(string: urls[index])!, placeholderImage: UIImage(named: "test"))
        
        return imageView
    }
    
    func updateChildView(childView: UIView, currIndex: Int, increaseIndex: Bool) {
        var index = 0
        let label = childView.viewWithTag(100) as! UILabel
        if increaseIndex {
            index = currIndex + 1
            if index > totalCount - 1 {
                index = 0
            }
        } else {
            index = currIndex - 1
            if index < 0 {
                index = totalCount - 1
            }
        }
        label.text = "Label:(index)"
        childView.tag = index
        (childView as! UIImageView).kf_setImageWithURL(NSURL(string: urls[index])!, placeholderImage: UIImage(named: "test"))
    }

}

创建一个空白工程,直接把这段代码拷贝黏贴。

图片下载用到了onecat的Kingfisher,自行下载。

注意配置一下info.plist,添加

<key>NSAppTransportSecurity</key>

<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>

</dict>

 Over

原文地址:https://www.cnblogs.com/emmet7life/p/5345899.html