如何实现一个无限循环,无缝衔接的图片轮播器 自己实现一次以后就不用使用轮播器的框架了
能用代码解决的问题就不在这里瞎BB了 O(∩_∩)O
首先先在Carousel文件件夹创建以下几个文件
CarouselFlowLayout.swift
CarouselView.swift
CarouselView.xib
CarsouselCell.swift
CarsouselCell.xib
Extension.swift
//CarouselFlowLayout.swift
import UIKit
class CarouselFlowLayout: UICollectionViewFlowLayout {
override func prepare() {
super.prepare()
itemSize = collectionView?.bounds.size ?? CGSize.zero
scrollDirection = .horizontal
minimumLineSpacing = 0
minimumInteritemSpacing = 0
collectionView?.isPagingEnabled = true
collectionView?.showsVerticalScrollIndicator = false
collectionView?.showsHorizontalScrollIndicator = false
}
}
// CarouselView.swift
//CarouselView.xib
import UIKit
private let kCellID = "CarsouselCellID"
private let kMultiple = 10000
/// 图片轮播器
public class CarouselView: UIView {
/// collectionView
@IBOutlet var collectionView: UICollectionView!
/// 页码指示器
@IBOutlet var pageControl: UIPageControl!
/// 图片地址集合
public var imageURLList: [String]? {
didSet {
collectionView.reloadData()
pageControl.numberOfPages = imageURLList?.count ?? 0
}
}
/// 定时器
var timer: Timer?
public override func awakeFromNib() {
super.awakeFromNib()
// 注册Cell
collectionView.register(UINib(nibName: "CarsouselCell", bundle: Bundle(for: CarsouselCell.self)), forCellWithReuseIdentifier: kCellID)
// 设置数据源
collectionView.dataSource = self
// 设置代理
collectionView.delegate = self
pageControl.hidesForSinglePage = true
}
public override func layoutSubviews() {
super.layoutSubviews()
collectionView.scrollToItem(at: IndexPath(item: (imageURLList?.count ?? 0) * Int(Float(kMultiple) * 0.5), section: 0), at: .left, animated: false)
}
}
// MARK: - 公共方法
extension CarouselView {
/// 获取图片轮播器
///
/// - returns: 图片轮播器对象
public static func carouselView() -> CarouselView{
return Bundle(for: CarouselView.self).loadNibNamed("CarouselView", owner: nil, options: nil)?.first as! CarouselView
}
/// 开始自动滚动
public func start() {
end()
timer = Timer.scheduledTimer(timeInterval: 3.0, target: self, selector: #selector(doTask), userInfo: nil, repeats: true)
RunLoop.main.add(timer!, forMode: .commonModes)
}
/// 停止自动滚动
public func end() {
timer?.invalidate()
timer = nil
}
@objc private func doTask() {
var contentOffset = collectionView.contentOffset
contentOffset.x += collectionView.frame.width
collectionView.setContentOffset(contentOffset, animated: true)
}
}
// MARK: - UICollectionViewDataSource
extension CarouselView: UICollectionViewDataSource {
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return (imageURLList?.count ?? 0) * kMultiple
}
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: kCellID, for: indexPath) as! CarsouselCell
cell.imageURL = imageURLList?[indexPath.item % (imageURLList?.count ?? 1)]
return cell
}
}
// MARK: - UICollectionViewDelegate
extension CarouselView: UICollectionViewDelegate {
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offsetPage = scrollView.contentOffset.x / scrollView.bounds.width
let currentIndex = Int(round(offsetPage))
pageControl.currentPage = currentIndex % (imageURLList?.count ?? 1)
}
public func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
end()
}
public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
start()
}
}
// CarsouselCell.swift
//CarsouselCell.xib
import UIKit
class CarsouselCell: UICollectionViewCell {
/// 图片区域
@IBOutlet var imageView: UIImageView!
var imageURL: String? {
didSet{
imageView.sd_setImage(path: imageURL)
}
}
}
// Extension.swift
import UIKit
import SDWebImage
extension UIImageView {
public func sd_setImage(path: String?) {
guard let noNullPath = path as? NSString else { return }
guard let newPath = noNullPath.addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed) else { return }
self.sd_setImage(with: URL(string: newPath))
}
}
到此图片轮播器的代码已经over了
在项目中如何使用呢?
// ViewController.swift
// Carousel
import UIKit
import Carousel
class ViewController: UIViewController {
lazy var cv: CarouselView = CarouselView.carouselView()
override func viewDidLoad() {
super.viewDidLoad()
cv.frame = CGRect(x: 0, y: 100, width: UIScreen.main.bounds.width, height: 150)
cv.imageURLList = ["http://www.17sucai.com/preview/569922/2016-06-30/轮播/images/3.jpg", "http://www.17sucai.com/preview/569922/2016-06-30/轮播/images/1.jpg"]
view.addSubview(cv)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
cv.start()
}
}