之前写过oc版本的无限滚动轮播图,现在来一个swift版本全部使用snapKit布局,数字还是pageConrrol样式可选
- enum typeStyle: Int {
- case pageControl
- case label
- }
效果图:
代码:
- //
- // TYCarouselView.swift
- // hxquan-swift
- //
- // Created by Tiny on 2018/11/12.
- // Copyright © 2018年 hxq. All rights reserved.
- // 轮播图
-
- import UIKit
-
- let ImgPlaceHolder = UIImage(named: "picture")
-
- enum typeStyle: Int {
- case pageControl
- case label
- }
-
- class TYCarouselCell: UICollectionViewCell {
-
- var url: String = ""{
- didSet{
- let cacheImg = SDImageCache.shared().imageFromDiskCache(forKey: url)
- imgView.contentMode = .center
- imgView.sd_setImage(with: URL(string: url),placeholderImage:cacheImg ?? ImgPlaceHolder) { [unowned self] (image, error, _, _) in
- if image != nil && error == nil{
- self.imgView.contentMode = .scaleAspectFill
- }
- }
- }
- }
-
- lazy var imgView: UIImageView = {
- let imgView = UIImageView()
- imgView.layer.masksToBounds = true
- imgView.contentMode = .center
- imgView.image = ImgPlaceHolder
- return imgView
- }()
-
- override init(frame: CGRect) {
- super.init(frame: frame)
- setupUI()
- }
-
- required init?(coder aDecoder: NSCoder) {
- super.init(coder: aDecoder)
- setupUI()
- }
-
- func setupUI(){
- contentView.addSubview(imgView)
-
- imgView.snp.makeConstraints { (make) in
- make.edges.equalToSuperview()
- }
- }
- }
-
- class TYCarouselView: UIView {
-
- var style: typeStyle = .pageControl{
- didSet{
- if style == .pageControl{
- if pageControl.superview == nil{
- addSubview(pageControl)
- pageControl.snp.makeConstraints { (make) in
- make.centerX.equalToSuperview()
- make.bottom.equalToSuperview().offset(-10)
- }
- }
- if label.superview != nil{
- label.removeFromSuperview()
- }
- }else{
- if label.superview == nil{
- addSubview(label)
- label.snp.makeConstraints { (make) in
- make.right.equalToSuperview().offset(-20)
- make.bottom.equalToSuperview().offset(-20)
- }
- }
- if pageControl.superview != nil{
- pageControl.removeFromSuperview()
- }
- }
- }
- }
-
- /// 定时器是否开启
- var isTimerEnable = true
-
- fileprivate let maxsection: Int = 100
-
- /// 滚动间隔
- public let scroInterval: TimeInterval = 4
-
- private var selectonBlock: ((Int)->Void)?
-
- public var images = [String]() {
- didSet{
- //重写images set方法
- //更新数据源
- collectionView.reloadData()
- if style == .pageControl {
- pageControl.numberOfPages = images.count
- }else{
- if oldValue.count == 0{
- label.attributedText = labelAttrText(1)
- }
- label.isHidden = images.count == 0
- }
- if isTimerEnable && !images.isEmpty{
- timerStart()
- }
- }
- }
-
- lazy var pageControl: UIPageControl = {
- let pageControl = UIPageControl()
- pageControl.sizeToFit()
- return pageControl
- }()
-
- lazy var label: UILabel = {
- let label = UILabel()
- label.font = UIFont.systemFont(ofSize: 12)
- label.textColor = UIColor.white
- label.attributedText = labelAttrText(0)
- label.isHidden = true
- return label
- }()
-
- fileprivate lazy var collectionView: UICollectionView = { [unowned self] in
- let layout = UICollectionViewFlowLayout()
- layout.scrollDirection = .horizontal
- layout.minimumLineSpacing = 0
- layout.minimumInteritemSpacing = 0
- layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
- let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
- collectionView.backgroundColor = UIColor.white
- collectionView.showsVerticalScrollIndicator = false
- collectionView.showsHorizontalScrollIndicator = false
- collectionView.delegate = self
- collectionView.dataSource = self
- collectionView.isPagingEnabled = true
- collectionView.register(TYCarouselCell.self, forCellWithReuseIdentifier: "TYCarouselCell")
-
- return collectionView
- }()
-
- fileprivate lazy var timer: Timer = { [unowned self] in
- let timer = Timer(timeInterval: scroInterval, target: self, selector: #selector(timerInterval), userInfo: nil, repeats: true)
- RunLoop.current.add(timer, forMode: .common)
- return timer
- }()
-
-
- override init(frame: CGRect) {
- super.init(frame: frame)
- setupUI()
- }
-
- convenience init(frame: CGRect,selectonBlock: ((Int)->Void)?){
- self.init(frame: frame)
- self.selectonBlock = selectonBlock
- }
-
- required init?(coder aDecoder: NSCoder) {
- super.init(coder: aDecoder)
- }
-
- private func setupUI(){
- addSubview(collectionView)
- collectionView.snp.makeConstraints { (make) in
- make.edges.equalToSuperview()
- }
-
- addSubview(pageControl)
- pageControl.snp.makeConstraints { (make) in
- make.bottom.equalToSuperview().offset(-10)
- make.centerX.equalToSuperview()
- }
- }
-
- @objc func timerInterval(){
- //取当前idnexPath
- if let currentIndexPath = collectionView.indexPathsForVisibleItems.last{
- //先让collectionViev滚动到中间
- let currentIndexPathReset = IndexPath(row: currentIndexPath.row, section: maxsection/2)
- collectionView.scrollToItem(at: currentIndexPathReset, at: .left, animated: false)
-
- //让当前indexPath.row++
- var row = currentIndexPath.row + 1
- var nextsection = currentIndexPathReset.section
- if row >= images.count{
- row = 0
- nextsection = nextsection + 1
- }
- if style == .pageControl {
- pageControl.currentPage = row
- }else{
- label.attributedText = labelAttrText(row+1)
- }
- let nextIndexPath = IndexPath(row: row, section:nextsection)
- collectionView.scrollToItem(at: nextIndexPath, at: .left, animated: true)
- }
- }
-
- private func timerStart(){
- if !timer.isValid {
- timer.fire()
- }
- }
-
- private func timerPause(){
- if timer.isValid {
- timer.invalidate()
- }
- }
-
- private func labelAttrText(_ index: Int) -> NSAttributedString{
- let lf = "\(index)"
- let rt = "\(images.count)"
- let str = lf + "/" + rt
- let attr = NSMutableAttributedString(string: str)
- attr.setAttributes([NSAttributedString.Key.foregroundColor : UIColor.red], range: NSRange(location: 0, length: 1))
- return attr
- }
- }
-
- extension TYCarouselView: UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout{
-
- func numberOfSections(in collectionView: UICollectionView) -> Int {
- return maxsection
- }
-
- func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
- return images.count
- }
-
- func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
- let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TYCarouselCell", for: indexPath) as! TYCarouselCell
- cell.url = images[indexPath.row]
- return cell
- }
-
- func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
- return CGSize(width: self.bounds.size.width, height: self.bounds.size.height)
- }
-
- func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
- selectonBlock?(indexPath.row)
- }
-
- //结束滚动
- func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
- let index = Int(scrollView.contentOffset.x / self.bounds.size.width + 0.5) % images.count
- if style == .pageControl {
- pageControl.currentPage = index
- }else{
- label.attributedText = labelAttrText(index+1)
- }
- if(isTimerEnable){
- //定时器启动
- if timer.isValid {
- timer.fireDate = Date.init(timeIntervalSinceNow: scroInterval)
- }
- }
- }
-
- //拖动
- func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
- if isTimerEnable{
- //定时器暂停
- if timer.isValid {
- timer.fireDate = Date.distantFuture
- }
- }
- }
- }
使用方法:
- lazy var carouselView: TYCarouselView = { [unowned self] in
- let carouselView = TYCarouselView(frame: .zero, selectonBlock: { (index) in
- print("\(index)")
- })
- carouselView.style = .label
- carouselView.layer.masksToBounds = true
- carouselView.layer.cornerRadius = 10
- return carouselView
- }()
-
- override func viewDidLoad() {
- super.viewDidLoad()
- //添加到父视图
- view.addSubview(carouselView)
- //设置约束
- carouselView.snp.makeConstraints { (make) in
- make.left.equalTo(15)
- make.right.equalTo(-15)
- make.top.equalTo(10)
- make.height.equalTo(170)
- }
- //设置数据源
- var imgs = [String]()
- for _ in 0..<5{
- imgs.append("图url")
- }
- self.carouselView.images = imgs
- }