// // JJPageControl.swift // JJPageControl // // https://github.com/zxhkit/JJPageControl // Created by xuanhe on 2022/9/1. // import UIKit enum JJPageControlAliment { case Center case Left case Right } protocol JJPageControlDelegate { func jj_pageControlClick(pageControl: JJPageControl, index: Int) } class JJPageControl: UIControl { /// 闭包点击事件 var clickPointClosure: ((_ num : Int) -> Void)? /// 当前点的大小 var currentPointSize: CGSize = CGSize(width: 6, height: 6) { didSet{ assert((currentPointSize.width >= 1 && currentPointSize.height >= 1), "Parameter value is not valid. currentPointSize must be greater than 1.") if numberOfPages > 0 { createPointView() } } } /// 其他点的大小 var otherPointSize: CGSize = CGSize(width: 6, height: 6) { didSet{ assert((otherPointSize.width >= 1 && otherPointSize.height >= 1), "Parameter value is not valid. otherPointSize must be greater than 1.") if numberOfPages > 0 { createPointView() } } } /// 点-切圆角 var pointCornerRadius:CGFloat = 3 { didSet{ if numberOfPages > 0 { createPointView() } } } /// 位置 var pageAliment: JJPageControlAliment = .Center { didSet{ if numberOfPages > 0 { createPointView() } } } /// 分页数量 var numberOfPages: Int = 0 { didSet{ if oldValue != numberOfPages { createPointView() } } } /// 当前点所在下标 var currentPage: Int = 0 { didSet{ if currentPage >= 0 { exchangePointView(oldValue, currentPage) }else{ currentPage = 0 } } } ///点的间距 var controlSpacing: CGFloat = 8 { didSet{ if numberOfPages > 0 { createPointView() } } } ///左右间距 var leftAndRightSpacing: CGFloat = 10 { didSet{ if leftAndRightSpacing < 0 { leftAndRightSpacing = 0 }else{ if numberOfPages > 0 { createPointView() } } } } /// 其他点未选中颜色 var otherColor: UIColor = .gray { didSet{ if numberOfPages > 0 { createPointView() } } } /// 当前点颜色 var currentColor: UIColor = .orange { didSet{ if numberOfPages > 0 { createPointView() } } } /// 其他点背景图片 var otherBkImage: UIImage? { didSet{ if numberOfPages > 0 { createPointView() } } } /// 当前点背景图片 var currentBkImage: UIImage? { didSet{ if numberOfPages > 0 { createPointView() } } } ///当前选中点的layer宽 var currentLayerBorderWidth: CGFloat = 1 { didSet{ if numberOfPages > 0 { createPointView() } } } ///其他点的layer宽 var otherLayerBorderWidth: CGFloat = 1 { didSet{ if numberOfPages > 0 { createPointView() } } } ///当前选中点的layer颜色 var currentLayerBorderColor: UIColor? { didSet{ if numberOfPages > 0 { createPointView() } } } ///其他选中点的layer颜色 var otherLayerBorderColor: UIColor? { didSet{ if numberOfPages > 0 { createPointView() } } } /// 当只有一个点的时候是否隐藏 var isHidesForSinglePage = true { didSet{ if numberOfPages > 0 { createPointView() } } } /// 是否可以点击 默认不可以点击 var isCanClickPoint = false { didSet{ if numberOfPages > 0 { createPointView() } } } /// 重写设置frame override var frame:CGRect { didSet{ let mainWidth = (CGFloat(numberOfPages) - 1) * otherPointSize.width + (CGFloat(numberOfPages) - 1) * controlSpacing + currentPointSize.width + leftAndRightSpacing * 2 if frame.width < mainWidth { frame.size.width = mainWidth } let max_height = max(otherPointSize.height, currentPointSize.height) if frame.height < max_height { frame.size.height = max_height } createPointView() } } /// 协议代理 var delegate:JJPageControlDelegate? private var dots = [UIImageView]() /// 创建视图 private func createPointView() { /// 先清除视图 clearView() if numberOfPages <= 0 { return } if isHidesForSinglePage == true ,numberOfPages == 1{ return } //居中控件 var startX:CGFloat = 0 var startY_current:CGFloat = 0 var startY_other:CGFloat = 0 let mainWidth = (CGFloat(numberOfPages) - 1) * otherPointSize.width + (CGFloat(numberOfPages) - 1) * controlSpacing + currentPointSize.width + leftAndRightSpacing * 2 + 1 if frame.width < mainWidth { frame.size.width = mainWidth }else{ if pageAliment == .Left { startX = leftAndRightSpacing } else if pageAliment == .Center { startX = (self.frame.size.width - mainWidth)/2.0 } else { startX = frame.width - mainWidth } } let max_height = max(otherPointSize.height, currentPointSize.height) if frame.height < max_height { frame.size.height = max_height startY_current = max_height - currentPointSize.height startY_other = max_height - otherPointSize.height } else { startY_current = (frame.height - max_height)/2.0 + (max_height - currentPointSize.height) startY_other = (frame.height - max_height)/2.0 + (max_height - otherPointSize.height) } for page in 0..= 0 { currentPage = index delegate?.jj_pageControlClick(pageControl: self, index: index) if let closure = self.clickPointClosure { closure(index) } } } } func clearView() { // subviews.forEach { subView in // subView.removeFromSuperview() // } subviews.forEach { $0.removeFromSuperview()} dots.removeAll() } func exchangePointView(_ oldPage: Int, _ newPage: Int) { if oldPage == newPage { return } if oldPage > dots.count { return } if newPage > dots.count { return } let oldDot = dots[oldPage] let oldFrame = oldDot.frame let newDot = dots[newPage] let newFrame = newDot.frame newDot.image = currentBkImage if let _ = currentBkImage { newDot.backgroundColor = .clear }else{ newDot.backgroundColor = currentColor } oldDot.image = otherBkImage if let _ = otherBkImage { oldDot.backgroundColor = .clear }else{ oldDot.backgroundColor = otherColor } if self.currentLayerBorderColor != nil { newDot.layer.borderColor = self.currentLayerBorderColor?.cgColor newDot.layer.borderWidth = self.currentLayerBorderWidth }else{ newDot.layer.borderWidth = 0 } if self.otherLayerBorderColor != nil { oldDot.layer.borderColor = self.otherLayerBorderColor?.cgColor oldDot.layer.borderWidth = self.otherLayerBorderWidth }else{ oldDot.layer.borderWidth = 0 } var oldMinx = oldFrame.minX var newMinx = newFrame.minX UIView.animate(withDuration: 0.25) { if newPage < oldPage { oldMinx = oldMinx + (self.currentPointSize.width - self.otherPointSize.width) } oldDot.frame = CGRect(x: oldMinx, y: newFrame.minY, width: self.otherPointSize.width, height: self.otherPointSize.height) if newPage > oldPage { newMinx = newMinx - (self.currentPointSize.width - self.otherPointSize.width) } newDot.frame = CGRect(x: newMinx, y: oldFrame.minY, width: self.currentPointSize.width, height: self.currentPointSize.height) if newPage - oldPage > 1 { //往右滑动 for index in (oldPage+1).. oldPage { newMinx = newMinx - (self.currentPointSize.width - self.otherPointSize.width) } newDot.frame = CGRect(x: newMinx, y: oldFrame.minY, width: self.currentPointSize.width, height: self.currentPointSize.height) if newPage - oldPage > 1 { //往右滑动 for index in (oldPage+1)..