简体   繁体   中英

How to change page control dot size and spacing in swift?

在此处输入图像描述

I want customize page control like a image.
I've already search that, but there are only deal scale.
I want change width, height, spacing.
How can I do that?

I tried this

class DefaultPageControl: UIPageControl {

    override var currentPage: Int {
        didSet {
            updateDots()
        }
    }

    func updateDots() {
        let currentDot = subviews[currentPage]

        subviews.forEach {
            $0.frame.size = ($0 == currentDot) ? CGSize(width: 16, height: 4) : CGSize(width: 8, height: 4)
            $0.layer.cornerRadius = 2
        }
    }
}

But how to change distance??

@oddK Can you try with this below answer. It's my assumption.

    class DefaultPageControl: UIPageControl {

    override var currentPage: Int {
        didSet {
            updateDots()
        }
    }

    func updateDots() {
        let currentDot = subviews[currentPage]

        let spacing = 5.0

        subviews.forEach {
            $0.frame = ($0 == currentDot) ? CGRect(x: 0, y: 0, width: 16, height: 4) : CGRect(x: spacing, y: 0, width: 8, height: 4)
            //$0.frame.size = ($0 == currentDot) ? CGSize(width: 16, height: 4) : CGSize(width: 8, height: 4)
            $0.layer.cornerRadius = 2
        }
    }
}

The default UIPageControll is not flexible.

class ExtendedpageControll: UIView{
 var numberOfPage: Int
 var currentpage : Int                  = 0{didSet{reloadView()}}
 var currentIndicatorColor: UIColor     = .black
 var indicatorColor: UIColor            = UIColor(white: 0.9, alpha: 1)
 var circleIndicator: Bool              = false
 private var dotView                    = [UIView]()
 private let spacing: CGFloat           = 6
 private lazy var  extraWidth: CGFloat  = circleIndicator ? 6 : 4

 init(numberOfPages: Int,currentPage: Int,isCircular: Bool){
    self.numberOfPage    = numberOfPages
    self.currentpage     = currentPage
    self.circleIndicator = isCircular
    super.init(frame: .zero)
    configView()
}
 required init?(coder: NSCoder) {fatalError("not implemented")}

 private func configView(){
    backgroundColor = .clear
    (0..<numberOfPage).forEach { _ in
        let view = UIView()
        addSubview(view)
        dotView.append(view)
    }
 }

 private func reloadView(){
    dotView.forEach{$0.backgroundColor = indicatorColor}
    dotView[currentpage].backgroundColor = currentIndicatorColor
    UIView.animate(withDuration: 0.2) {
        self.dotView[self.currentpage].frame.origin.x   = self.dotView[self.currentpage].frame.origin.x - self.extraWidth
        self.dotView[self.currentpage].frame.size.width = self.dotView[self.currentpage].frame.size.width + (self.extraWidth * 2)
    }
}

 override func layoutSubviews() {
    super.layoutSubviews()
    for (i,view) in dotView.enumerated(){
        view.clipsToBounds      = true
        view.layer.cornerRadius = bounds.height / 2
        let width: CGFloat      = circleIndicator ? self.bounds.height : CGFloat(self.bounds.width / CGFloat(self.numberOfPage) - self.spacing) - self.extraWidth
        UIView.animate(withDuration: 0.2) {
          view.frame = CGRect(x: ((self.bounds.width / CGFloat(self.numberOfPage)) * CGFloat(i)) + self.spacing, y: 0, width: width , height: self.bounds.height)
        }
    }
    reloadView()
}
}

Usage : If you want to link ExtendedpageControll to a View Such as CollectionView Just Do like this: (item is your Datamodel)

class SampleViewController: UIViewController{

let colectionView = UICollectionView()

lazy var pageControll: ExtendedpageControll = {
    let pc                   = ExtendedpageControll(numberOfPages: items.count, currentPage: 0,isCircular: true)
    pc.currentIndicatorColor = .black
    return pc
}()

func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    
        if pageControll.currentpage == indexPath.row {
            guard let visible = self.collectionView.visibleCells.first else { return }
            guard let index = self.collectionView.indexPath(for: visible)?.row else { return }
            pageControll.currentpage = index
        }

   } 
}

inside init , you can set the shape of the indicator to be circular or extended via isCircular .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM