效果图如下:
实现思路:
利用n+2个元素实现
实现步骤:
1.自定义View,添加scrollView,pageControl和timer
class ImageCircleView: UIView {
var imagesArr:[String]? {
didSet {
setupImageViews()
}
}
var newImagesArr:[String] = [String]()
var timer: Timer!
var scrollView: UIScrollView!
var pageControl: UIPageControl!
var imageWidth: CGFloat = 0
var imageCount: Int = 0
var currentIndex: Int = 0
var duration: TimeInterval = 3.0
var pageColor: UIColor = UIColor.white
var currentPageColor: UIColor = UIColor.black
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupUI() -> Void {
setupScrollView()
setupPageControl()
setupTimer()
}
func setupScrollView() -> Void {
scrollView = UIScrollView(frame: self.bounds)
scrollView.delegate = self
scrollView.isPagingEnabled = true
scrollView.showsHorizontalScrollIndicator = false
scrollView.showsVerticalScrollIndicator = false
addSubview(scrollView)
}
func setupPageControl() -> Void {
pageControl = UIPageControl(frame: CGRect(x: (self.frame.width - 200) * 0.5, y: self.frame.size.height * 0.8, width: 200, height: 20))
pageControl.currentPageIndicatorTintColor = currentPageColor
pageControl.pageIndicatorTintColor = pageColor
addSubview(pageControl)
}
func setupImageViews() -> Void {
guard let images = imagesArr else {
return
}
guard let first = images.first, let last = images.last else {
return
}
newImagesArr.removeAll()
_ = scrollView.subviews.map { (view) -> Void in
view.removeFromSuperview()
}
if images.count == 1 {
removeTimer()
newImagesArr += images
}else {
newImagesArr.append(last)
newImagesArr += images
newImagesArr.append(first)
}
imageCount = images.count
pageControl.numberOfPages = imageCount
let imageW:CGFloat = self.frame.size.width
let imageH:CGFloat = self.frame.size.height
var imageX:CGFloat = 0
let imageY:CGFloat = 0
imageWidth = imageW
scrollView.contentSize = CGSize(width: CGFloat(newImagesArr.count) * imageWidth, height: imageH)
scrollView.setContentOffset(imageCount > 1 ? CGPoint(x: imageWidth, y: 0) : CGPoint.zero, animated: true)
currentIndex = 0
for i in 0..<newImagesArr.count {
imageX = imageW * CGFloat(i)
let imageView = UIImageView(frame: CGRect(x: imageX, y: imageY, width: imageW, height: imageH))
imageView.image = UIImage(named: newImagesArr[i])
scrollView.addSubview(imageView)
}
}
//Mark: - Timer
func setupTimer() -> Void {
timer = Timer(timeInterval: duration, target: self, selector: #selector(nextPage), userInfo: nil, repeats: true)
RunLoop.main.add(timer, forMode: RunLoopMode.commonModes)
}
func nextPage() -> Void {
pauseTimer()
// currentIndex += 1
var offset = scrollView.contentOffset
offset.x += imageWidth
scrollView.setContentOffset(offset, animated: true)
}
func removeTimer() -> Void {
if timer != nil {
timer.invalidate()
timer = nil
}
}
func pauseTimer() -> Void {
if timer.isValid {
timer.fireDate = Date.distantFuture
}
}
func openTimer() -> Void {
if timer.isValid {
timer.fireDate = Date(timeIntervalSinceNow: duration)
}
}
deinit {
removeTimer()
}
}
2.在控制器中的代理方法
extension ImageCircleView: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
currentIndex = Int(self.scrollView.contentOffset.x / imageWidth) - 1
if self.scrollView.contentOffset.x <= 0 {
currentIndex = imageCount - 1
self.scrollView.setContentOffset(CGPoint(x: CGFloat(imageCount) * imageWidth, y: 0), animated: false)
}
if self.scrollView.contentOffset.x >= CGFloat(imageCount + 1) * imageWidth {
currentIndex = 0
self.scrollView.setContentOffset(CGPoint(x: imageWidth, y: 0), animated: false)
}
pageControl.currentPage = currentIndex
}
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
openTimer()
}
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
pauseTimer()
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
openTimer()
}
}
3.在控制器中使用:
import UIKit
class ImageCircleViewController: UIViewController {
var imageCircleView:ImageCircleView = ImageCircleView(frame:CGRect(x: 0, y: 30, width: UIScreen.main.bounds.size.width, height: 260))
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.white
setupUI()
}
func setupUI() -> Void {
imageCircleView.imagesArr = ["01","02","03","04","05","06"]
imageCircleView.backgroundColor = UIColor.lightGray
view.addSubview(imageCircleView)
}
}