1、轮播图的协议
protocol SMCarouselViewDelegate: NSObjectProtocol {
func mCarouselView(_ carouselView: SMCarouselView, didSelectItemAt index: Int);
}
2、轮播视图:SMCarouselView
class SMCarouselView: UIView {
private lazy var layout: UICollectionViewFlowLayout = {
let layout = UICollectionViewFlowLayout()
layout.minimumInteritemSpacing = 0
layout.scrollDirection = .horizontal
layout.minimumLineSpacing = 0
layout.sectionInset = UIEdgeInsets(top: 0, left: 0 , bottom: 0, right: 0)
return layout
}()
private lazy var collectionView: UICollectionView = {
let collection = UICollectionView(frame: .zero, collectionViewLayout: self.layout)
collection.backgroundColor = UIColor.white
collection.delegate = self
collection.dataSource = self
collection.isPagingEnabled = true
collection.bounces = false
collection.showsHorizontalScrollIndicator = false
collection.register(SMCarouselCell.self, forCellWithReuseIdentifier: "SMCarouselCell")
return collection
}()
private lazy var pageControl: SMPageControl = {
let pageControl = SMPageControl()
pageControl.contentHorizontalAlignment = .right
pageControl.isUserInteractionEnabled = false
let currentPageImg = UIImage.imageWithColor(UIColor(hex: "1F59EE")!,size: CGSize(width: 14, height: 4))
let pageImg = UIImage.imageWithColor(UIColor.white.withAlphaComponent(0.5),size: CGSize(width: 4, height: 4))
pageControl.currentPageIndicatorTintColor = UIColor(r: 33, g: 89, b: 237)
pageControl.pageIndicatorTintColor = UIColor(r: 216, g: 216, b: 216)
pageControl.currentPage = 0
return pageControl
}()
private var timer: Timer? = nil
private var isAutoScroll: Bool = false
private var dataArray = [Any]()
private var maxCount = 0
weak var mCarouselViewDelegate: SMCarouselViewDelegate?
override init(frame: CGRect) {
super.init(frame: frame)
self.addSubview(self.collectionView)
self.addSubview(self.pageControl)
setTimer()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
deinit {
Log.info(text: "销毁了???")
}
override func layoutSubviews() {
super.layoutSubviews()
self.collectionView.frame = CGRect(x: 0, y: 0, width: self.bounds.size.width, height: self.bounds.size.height)
self.pageControl.frame = CGRect(x: 0, y: self.bounds.size.height - 15, width: self.bounds.size.width - 8, height: 10)
}
func setDataArray(dataArray: [Any]) {
guard dataArray.count > 0 else {
return
}
self.dataArray = dataArray
maxCount = self.dataArray.count
isAutoScroll = self.dataArray.count == 1 ? false : true
if isAutoScroll {
self.pageControl.numberOfPages = maxCount
}else {
removeTimer()
self.pageControl.numberOfPages = 0
}
self.collectionView.reloadData()
}
private func setTimer() {
if self.timer == nil {
let timer = Timer(timeInterval: 2, repeats: true, block: { [weak self] (_) in
self?.nextPage()
})
RunLoop.current.add(timer, forMode: RunLoop.Mode.common)
self.timer = timer
}
}
private func nextPage() {
let currentIndexPath = collectionView.indexPathsForVisibleItems.last!
scrollToItem(at: IndexPath(item: currentIndexPath.item, section: 0), at: .left, animated: false)
var nextItem = currentIndexPath.item + 1
var section = 0
if (nextItem == maxCount) {
nextItem = 0
section = 1
}
let nextIndexPath = IndexPath(item: nextItem, section: section)
scrollToItem(at: nextIndexPath, at: .left, animated: true)
}
private func scrollToItem(at indexPath: IndexPath, at scrollPosition: UICollectionView.ScrollPosition, animated: Bool) {
self.collectionView.scrollToItem(at: indexPath, at: scrollPosition, animated: animated)
}
private func lastVisibleItemHandle() {
let currentIndexPath = collectionView.indexPathsForVisibleItems.last!
scrollToItem(at: IndexPath(item: currentIndexPath.item, section: 0), at: .left, animated: false)
}
private func removeTimer() {
self.timer?.invalidate()
self.timer = nil
}
private func resumeTimer() {
setTimer()
}
private func getCurrentIndex(scrollView: UIScrollView) -> Int {
let currentIndex = Int((scrollView.contentOffset.x/scrollView.frame.size.width + 0.5)) % maxCount
return currentIndex
}
}
extension SMCarouselView: UICollectionViewDelegateFlowLayout,UICollectionViewDataSource {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return isAutoScroll ? 2 : 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return maxCount
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SMCarouselCell", for: indexPath)
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) {
self.mCarouselViewDelegate?.mCarouselView(self, didSelectItemAt: indexPath.item)
}
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
if isAutoScroll {
removeTimer()
if (maxCount - 1 == getCurrentIndex(scrollView: scrollView)) {
lastVisibleItemHandle()
}
}
}
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
if isAutoScroll {
resumeTimer()
}
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if isAutoScroll {
let currentIndex = getCurrentIndex(scrollView: scrollView)
self.pageControl.currentPage = currentIndex
}
}
}
3、轮播视图的cell
class SMCarouselCell: UICollectionViewCell {
private let imageView = UIImageView()
override init(frame: CGRect) {
super.init(frame: frame)
imageView.image = UIImage(named: "roleplacehoder")
self.contentView.addSubview(imageView)
}
override func layoutSubviews() {
super.layoutSubviews()
imageView.frame = self.bounds
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
// let view = super.hitTest(point, with: event)
// if let _ = view as? UICollectionView {
// return self
// }
// return super.hitTest(point, with: event)
// }
}
网友评论