Swift Control ImageCarouselView图片轮播器(源码)
一直觉得自己写的不是技术而是情怀一个个的教程是自己这一路走来的痕迹。靠专业技能的成功是最具可复制性的希望我的这条路能让你们少走弯路希望我能帮你们抹去知识的蒙尘希望我能帮你们理清知识的脉络希望未来技术之巅上有你们也有我。Swift-Banner(图片轮播)示例代码banner本地图片文章目录效果说明使用源码效果说明图片提供一下功能是否开启卡片缩放效果是否自动轮播轮播时间显示 pageControlpageControl颜色设置圆角设置占位图加载网络图片点击事件监听滚动事件使用import UIKit import SnapKit class ViewController:UIViewController{lazy private var imageCarouselView:ImageCarouselView{let viewImageCarouselView()// 是否开启卡片缩放效果view.isCardZoomEnabledtrue// 自动轮播view.isAutoScrolltrue// 轮播时间view.autoScrollTime2// 显示 pageControlview.showPageControltrue// pageControl颜色view.currentPageColor.white view.pageColorUIColor.white.withAlphaComponent(0.3)// 圆角view.layer.cornerRadius16view.clipsToBoundstrue// 占位图view.placeholderImageUIImage(named:placeholder_1)// 网络图片view.remoteImages[https://picsum.photos/id/1015/800/400,https://picsum.photos/id/1016/800/400,https://picsum.photos/id/1018/800/400,https://picsum.photos/id/1020/800/400]// 点击事件view.didTapImageBlock{index inprint(点击了第 \(index) 张图片)}// 滚动事件view.didScrollToIndexBlock{index inprint(当前轮播到第 \(index) 张)}returnview}()override funcviewDidLoad(){super.viewDidLoad()view.backgroundColor.white view.addSubview(imageCarouselView)imageCarouselView.snp.makeConstraints{make in make.top.equalToSuperview().offset(120)make.left.equalToSuperview().offset(20)make.right.equalToSuperview().offset(-20)make.height.equalTo(220)}}}源码import UIKit import SnapKit import Kingfisher class ImageCarouselView:UIView{// MARK: - 对外属性/// 是否自动轮播var isAutoScroll:Booltrue{didSet{setupTimer()}}/// 自动轮播时间var autoScrollTime:TimeInterval3{didSet{setupTimer()}}/// 是否显示 pageControlvar showPageControl:Booltrue{didSet{pageControl.isHidden!showPageControl}}/// pageControl 当前颜色var currentPageColor:UIColor.white{didSet{pageControl.currentPageIndicatorTintColorcurrentPageColor}}/// pageControl 默认颜色var pageColor:UIColorUIColor.white.withAlphaComponent(0.4){didSet{pageControl.pageIndicatorTintColorpageColor}}/// 占位图var placeholderImage:UIImage?/// 本地图片数组var localImages:[String][]{didSet{imageType.localreloadData()}}/// 网络图片数组var remoteImages:[String][]{didSet{imageType.remotereloadData()}}/// 点击图片回调var didTapImageBlock:((Int)-Void)?/// 滚动到图片回调var didScrollToIndexBlock:((Int)-Void)?// MARK: - PrivateprivateenumImageType{caselocalcaseremote}private var imageType:ImageType.local private var timer:Timer?private let maxSections100private var imageCount:Int{switchimageType{case.local:returnlocalImages.countcase.remote:returnremoteImages.count}}// MARK: - UIlazy private var collectionView:UICollectionView{let layoutUICollectionViewFlowLayout()layout.scrollDirection.horizontal layout.minimumLineSpacing0let viewUICollectionView(frame:.zero,collectionViewLayout:layout)view.backgroundColor.clear view.showsHorizontalScrollIndicatorfalse view.isPagingEnabledtrue view.delegateself view.dataSourceself view.register(ImageCarouselCell.self,forCellWithReuseIdentifier:ImageCarouselCell.identifier)returnview}()lazy private var pageControl:UIPageControl{let viewUIPageControl()view.currentPageIndicatorTintColorcurrentPageColor view.pageIndicatorTintColorpageColorreturnview}()// MARK: - Initoverrideinit(frame:CGRect){super.init(frame:frame)buildUI()}required init?(coder:NSCoder){fatalError()}deinit{timer?.invalidate()}}// MARK: - UIextension ImageCarouselView{private funcbuildUI(){addSubview(collectionView)addSubview(pageControl)collectionView.snp.makeConstraints{make in make.edges.equalToSuperview()}pageControl.snp.makeConstraints{make in make.centerX.equalToSuperview()make.bottom.equalToSuperview().offset(-10)}}}// MARK: - Dataextension ImageCarouselView{private funcreloadData(){pageControl.numberOfPagesimageCount collectionView.reloadData()layoutIfNeeded()guard imageCount0else{return}let middleSectionmaxSections/2let startIndexPathIndexPath(item:0,section:middleSection)collectionView.scrollToItem(at:startIndexPath,at:.left,animated:false)setupTimer()}}// MARK: - Timerextension ImageCarouselView{private funcsetupTimer(){timer?.invalidate()timernil guard isAutoScrollelse{return}guard imageCount1else{return}timerTimer.scheduledTimer(timeInterval:autoScrollTime,target:self,selector:#selector(autoScrollAction),userInfo:nil,repeats:true)RunLoop.main.add(timer!,forMode:.common)}objc private funcautoScrollAction(){guard let currentIndexPathcollectionView.indexPathsForVisibleItems.firstelse{return}var nextItemcurrentIndexPath.item1var nextSectioncurrentIndexPath.sectionifnextItemimageCount{nextItem0nextSection1}let nextIndexPathIndexPath(item:nextItem,section:nextSection)collectionView.scrollToItem(at:nextIndexPath,at:.left,animated:true)}}// MARK: - UICollectionViewextension ImageCarouselView:UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout{funcnumberOfSections(in collectionView:UICollectionView)-Int{returnmaxSections}funccollectionView(_ collectionView:UICollectionView,numberOfItemsInSection section:Int)-Int{returnimageCount}funccollectionView(_ collectionView:UICollectionView,cellForItemAt indexPath:IndexPath)-UICollectionViewCell{let cellcollectionView.dequeueReusableCell(withReuseIdentifier:ImageCarouselCell.identifier,for:indexPath)as!ImageCarouselCellswitchimageType{case.local:let imageNamelocalImages[indexPath.item]cell.imageView.imageUIImage(named:imageName)case.remote:let urlStringremoteImages[indexPath.item]guard let urlURL(string:urlString)else{returncell}cell.imageView.kf.setImage(with:url,placeholder:placeholderImage)}returncell}funccollectionView(_ collectionView:UICollectionView,layout collectionViewLayout:UICollectionViewLayout,sizeForItemAt indexPath:IndexPath)-CGSize{returncollectionView.bounds.size}funcscrollViewDidScroll(_ scrollView:UIScrollView){guard imageCount0else{return}let pageInt((scrollView.contentOffset.xscrollView.bounds.width*0.5)/scrollView.bounds.width)%imageCount pageControl.currentPagepage didScrollToIndexBlock?(page)}funccollectionView(_ collectionView:UICollectionView,didSelectItemAt indexPath:IndexPath){didTapImageBlock?(indexPath.item)}funcscrollViewWillBeginDragging(_ scrollView:UIScrollView){timer?.invalidate()}funcscrollViewDidEndDragging(_ scrollView:UIScrollView,willDecelerate decelerate:Bool){setupTimer()}}class ImageCarouselCell:UICollectionViewCell{staticlet identifierImageCarouselCelllazy var imageView:UIImageView{let viewUIImageView()view.contentMode.scaleAspectFill view.clipsToBoundstruereturnview}()overrideinit(frame:CGRect){super.init(frame:frame)contentView.addSubview(imageView)imageView.snp.makeConstraints{make in make.edges.equalToSuperview()}}required init?(coder:NSCoder){fatalError()}}