当前位置:   article > 正文

iOS swift版本无限滚动轮播图

ios swift版本无限滚动轮播图

之前写过oc版本的无限滚动轮播图,现在来一个swift版本全部使用snapKit布局,数字还是pageConrrol样式可选

  1. enum typeStyle: Int {
  2. case pageControl
  3. case label
  4. }

效果图:
950551-20181122145947642-1321787645.gif

代码:

  1. //
  2. // TYCarouselView.swift
  3. // hxquan-swift
  4. //
  5. // Created by Tiny on 2018/11/12.
  6. // Copyright © 2018年 hxq. All rights reserved.
  7. // 轮播图
  8. import UIKit
  9. let ImgPlaceHolder = UIImage(named: "picture")
  10. enum typeStyle: Int {
  11. case pageControl
  12. case label
  13. }
  14. class TYCarouselCell: UICollectionViewCell {
  15. var url: String = ""{
  16. didSet{
  17. let cacheImg = SDImageCache.shared().imageFromDiskCache(forKey: url)
  18. imgView.contentMode = .center
  19. imgView.sd_setImage(with: URL(string: url),placeholderImage:cacheImg ?? ImgPlaceHolder) { [unowned self] (image, error, _, _) in
  20. if image != nil && error == nil{
  21. self.imgView.contentMode = .scaleAspectFill
  22. }
  23. }
  24. }
  25. }
  26. lazy var imgView: UIImageView = {
  27. let imgView = UIImageView()
  28. imgView.layer.masksToBounds = true
  29. imgView.contentMode = .center
  30. imgView.image = ImgPlaceHolder
  31. return imgView
  32. }()
  33. override init(frame: CGRect) {
  34. super.init(frame: frame)
  35. setupUI()
  36. }
  37. required init?(coder aDecoder: NSCoder) {
  38. super.init(coder: aDecoder)
  39. setupUI()
  40. }
  41. func setupUI(){
  42. contentView.addSubview(imgView)
  43. imgView.snp.makeConstraints { (make) in
  44. make.edges.equalToSuperview()
  45. }
  46. }
  47. }
  48. class TYCarouselView: UIView {
  49. var style: typeStyle = .pageControl{
  50. didSet{
  51. if style == .pageControl{
  52. if pageControl.superview == nil{
  53. addSubview(pageControl)
  54. pageControl.snp.makeConstraints { (make) in
  55. make.centerX.equalToSuperview()
  56. make.bottom.equalToSuperview().offset(-10)
  57. }
  58. }
  59. if label.superview != nil{
  60. label.removeFromSuperview()
  61. }
  62. }else{
  63. if label.superview == nil{
  64. addSubview(label)
  65. label.snp.makeConstraints { (make) in
  66. make.right.equalToSuperview().offset(-20)
  67. make.bottom.equalToSuperview().offset(-20)
  68. }
  69. }
  70. if pageControl.superview != nil{
  71. pageControl.removeFromSuperview()
  72. }
  73. }
  74. }
  75. }
  76. /// 定时器是否开启
  77. var isTimerEnable = true
  78. fileprivate let maxsection: Int = 100
  79. /// 滚动间隔
  80. public let scroInterval: TimeInterval = 4
  81. private var selectonBlock: ((Int)->Void)?
  82. public var images = [String]() {
  83. didSet{
  84. //重写images set方法
  85. //更新数据源
  86. collectionView.reloadData()
  87. if style == .pageControl {
  88. pageControl.numberOfPages = images.count
  89. }else{
  90. if oldValue.count == 0{
  91. label.attributedText = labelAttrText(1)
  92. }
  93. label.isHidden = images.count == 0
  94. }
  95. if isTimerEnable && !images.isEmpty{
  96. timerStart()
  97. }
  98. }
  99. }
  100. lazy var pageControl: UIPageControl = {
  101. let pageControl = UIPageControl()
  102. pageControl.sizeToFit()
  103. return pageControl
  104. }()
  105. lazy var label: UILabel = {
  106. let label = UILabel()
  107. label.font = UIFont.systemFont(ofSize: 12)
  108. label.textColor = UIColor.white
  109. label.attributedText = labelAttrText(0)
  110. label.isHidden = true
  111. return label
  112. }()
  113. fileprivate lazy var collectionView: UICollectionView = { [unowned self] in
  114. let layout = UICollectionViewFlowLayout()
  115. layout.scrollDirection = .horizontal
  116. layout.minimumLineSpacing = 0
  117. layout.minimumInteritemSpacing = 0
  118. layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
  119. let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
  120. collectionView.backgroundColor = UIColor.white
  121. collectionView.showsVerticalScrollIndicator = false
  122. collectionView.showsHorizontalScrollIndicator = false
  123. collectionView.delegate = self
  124. collectionView.dataSource = self
  125. collectionView.isPagingEnabled = true
  126. collectionView.register(TYCarouselCell.self, forCellWithReuseIdentifier: "TYCarouselCell")
  127. return collectionView
  128. }()
  129. fileprivate lazy var timer: Timer = { [unowned self] in
  130. let timer = Timer(timeInterval: scroInterval, target: self, selector: #selector(timerInterval), userInfo: nil, repeats: true)
  131. RunLoop.current.add(timer, forMode: .common)
  132. return timer
  133. }()
  134. override init(frame: CGRect) {
  135. super.init(frame: frame)
  136. setupUI()
  137. }
  138. convenience init(frame: CGRect,selectonBlock: ((Int)->Void)?){
  139. self.init(frame: frame)
  140. self.selectonBlock = selectonBlock
  141. }
  142. required init?(coder aDecoder: NSCoder) {
  143. super.init(coder: aDecoder)
  144. }
  145. private func setupUI(){
  146. addSubview(collectionView)
  147. collectionView.snp.makeConstraints { (make) in
  148. make.edges.equalToSuperview()
  149. }
  150. addSubview(pageControl)
  151. pageControl.snp.makeConstraints { (make) in
  152. make.bottom.equalToSuperview().offset(-10)
  153. make.centerX.equalToSuperview()
  154. }
  155. }
  156. @objc func timerInterval(){
  157. //取当前idnexPath
  158. if let currentIndexPath = collectionView.indexPathsForVisibleItems.last{
  159. //先让collectionViev滚动到中间
  160. let currentIndexPathReset = IndexPath(row: currentIndexPath.row, section: maxsection/2)
  161. collectionView.scrollToItem(at: currentIndexPathReset, at: .left, animated: false)
  162. //让当前indexPath.row++
  163. var row = currentIndexPath.row + 1
  164. var nextsection = currentIndexPathReset.section
  165. if row >= images.count{
  166. row = 0
  167. nextsection = nextsection + 1
  168. }
  169. if style == .pageControl {
  170. pageControl.currentPage = row
  171. }else{
  172. label.attributedText = labelAttrText(row+1)
  173. }
  174. let nextIndexPath = IndexPath(row: row, section:nextsection)
  175. collectionView.scrollToItem(at: nextIndexPath, at: .left, animated: true)
  176. }
  177. }
  178. private func timerStart(){
  179. if !timer.isValid {
  180. timer.fire()
  181. }
  182. }
  183. private func timerPause(){
  184. if timer.isValid {
  185. timer.invalidate()
  186. }
  187. }
  188. private func labelAttrText(_ index: Int) -> NSAttributedString{
  189. let lf = "\(index)"
  190. let rt = "\(images.count)"
  191. let str = lf + "/" + rt
  192. let attr = NSMutableAttributedString(string: str)
  193. attr.setAttributes([NSAttributedString.Key.foregroundColor : UIColor.red], range: NSRange(location: 0, length: 1))
  194. return attr
  195. }
  196. }
  197. extension TYCarouselView: UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout{
  198. func numberOfSections(in collectionView: UICollectionView) -> Int {
  199. return maxsection
  200. }
  201. func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
  202. return images.count
  203. }
  204. func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  205. let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TYCarouselCell", for: indexPath) as! TYCarouselCell
  206. cell.url = images[indexPath.row]
  207. return cell
  208. }
  209. func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
  210. return CGSize(width: self.bounds.size.width, height: self.bounds.size.height)
  211. }
  212. func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
  213. selectonBlock?(indexPath.row)
  214. }
  215. //结束滚动
  216. func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
  217. let index = Int(scrollView.contentOffset.x / self.bounds.size.width + 0.5) % images.count
  218. if style == .pageControl {
  219. pageControl.currentPage = index
  220. }else{
  221. label.attributedText = labelAttrText(index+1)
  222. }
  223. if(isTimerEnable){
  224. //定时器启动
  225. if timer.isValid {
  226. timer.fireDate = Date.init(timeIntervalSinceNow: scroInterval)
  227. }
  228. }
  229. }
  230. //拖动
  231. func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
  232. if isTimerEnable{
  233. //定时器暂停
  234. if timer.isValid {
  235. timer.fireDate = Date.distantFuture
  236. }
  237. }
  238. }
  239. }

使用方法:

  1. lazy var carouselView: TYCarouselView = { [unowned self] in
  2. let carouselView = TYCarouselView(frame: .zero, selectonBlock: { (index) in
  3. print("\(index)")
  4. })
  5. carouselView.style = .label
  6. carouselView.layer.masksToBounds = true
  7. carouselView.layer.cornerRadius = 10
  8. return carouselView
  9. }()
  10. override func viewDidLoad() {
  11. super.viewDidLoad()
  12. //添加到父视图
  13. view.addSubview(carouselView)
  14. //设置约束
  15. carouselView.snp.makeConstraints { (make) in
  16. make.left.equalTo(15)
  17. make.right.equalTo(-15)
  18. make.top.equalTo(10)
  19. make.height.equalTo(170)
  20. }
  21. //设置数据源
  22. var imgs = [String]()
  23. for _ in 0..<5{
  24. imgs.append("图url")
  25. }
  26. self.carouselView.images = imgs
  27. }

转载于:https://www.cnblogs.com/qqcc1388/p/10000607.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/519788
推荐阅读
相关标签
  

闽ICP备14008679号