简体   繁体   中英

How to customize UIPageControl?

I am a beginner in swift

I want to customize my UIPageControl on only code

The UIPageControl style I want is:I can change the little dot above and when I switch to it he can change to another style

I found an article that provides a how-to , which can be done using

It's good, but I don't understand how it works

The method is attached for reference by friends who have the same needs

but that's not my real intention

I want to understand how this program works, can someone explain it to me? or provide a more simple and understandable method

I know so much code is because it supports versions below ios14

but I think this part may be omitted in explaining

The reason why it is not removed is to seek better and more complete code.

thank everybody

import UIKit

class CZPageControl: UIPageControl {
    
    var currentImage: UIImage?
    var inactiveImage: UIImage?
    var currentTintColor: UIColor?
    var inactiveTintColor: UIColor?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.isUserInteractionEnabled = false
        if #available(iOS 14.0, *) {
            self.allowsContinuousInteraction = false
        }
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override var currentPage: Int {
        didSet {
            updateDots()
        }
    }
    
    func updateDots() {
        guard let currentImage = self.currentImage, let inactiveImage = self.inactiveImage else {
            return
        }
        
        if #available(iOS 14.0, *) {
            guard let dotContentView = findIndicatorContentView() else {
                return
            }
            
            for (index, view) in dotContentView.subviews.enumerated() {
                if view.isKind(of: UIImageView.self) {
                    self.currentPageIndicatorTintColor = self.currentTintColor
                    self.pageIndicatorTintColor = self.inactiveTintColor
                    
                    let indicatorView = view as! UIImageView
                    indicatorView.image = nil
                    if index == self.currentPage {
                        indicatorView.image = currentImage.withRenderingMode(.alwaysTemplate)
                    } else {
                        indicatorView.image = inactiveImage.withRenderingMode(.alwaysTemplate)
                    }
                }
            }
        } else {
            for (index, view) in self.subviews.enumerated() {
                if let dot = imageViewForSubview(view, currentPage: index) {
                    var size = CGSize.zero
                    
                    if index == self.currentPage {
                        dot.tintColor = self.currentTintColor
                        dot.image = currentImage.withRenderingMode(.alwaysTemplate)
                        size = dot.image!.size
                    } else {
                        dot.tintColor = self.inactiveTintColor
                        dot.image = inactiveImage.withRenderingMode(.alwaysTemplate)
                        size = dot.image!.size
                    }
                    
                    if let superview = dot.superview {
                        let x = (superview.frame.size.width - size.width) / 2.0
                        let y = (superview.frame.size.height - size.height) / 2.0
                        dot.frame = CGRect(x: x, y: y, width: size.width, height: size.height)
                    }
                }
            }
        }
    }
    
    // iOS 14之前创建UIImageView使用
    func imageViewForSubview(_ view: UIView, currentPage: Int) -> UIImageView? {
        
        var dot: UIImageView?
        if view.isKind(of: UIView.self) {
            for subview in view.subviews {
                if subview.isKind(of: UIImageView.self) {
                    dot = (subview as! UIImageView)
                    break
                }
            }
            
            if dot == nil {
                dot = UIImageView(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height))
                view.addSubview(dot!)
            }
        } else {
            dot = (view as! UIImageView)
        }
        
        return dot
    }
    
    @available(iOS 14.0, *)
    func findIndicatorContentView() -> UIView? {
        for contentView in self.subviews {
            if let contentViewClass = NSClassFromString("_UIPageControlContentView"), contentView.isKind(of: contentViewClass) {
                for indicatorContentView in contentView.subviews {
                    if let indicatorContentViewClass = NSClassFromString("_UIPageControlIndicatorContentView"), indicatorContentView.isKind(of: indicatorContentViewClass) {
                        return indicatorContentView
                    }
                }
            }
        }
        return nil
    }


}


You will have to call "updateDots()" in viewDidAppear() and your valueChanged handler for the page control.

import UIKit

class CustomImagePageControl: UIPageControl {

  let activeImage:UIImage = UIImage(named: "SelectedPage")!
  let inactiveImage:UIImage = UIImage(named: "UnselectedPage")!

  override func awakeFromNib() {
        super.awakeFromNib()

        self.pageIndicatorTintColor = UIColor.clear
        self.currentPageIndicatorTintColor = UIColor.clear
        self.clipsToBounds = false
   }

   func updateDots() {
        var i = 0
        for view in self.subviews {
            if let imageView = self.imageForSubview(view) {
                if i == self.currentPage {
                    imageView.image = self.activeImage
                } else {
                    imageView.image = self.inactiveImage
                }
                i = i + 1
            } else {
                var dotImage = self.inactiveImage
                if i == self.currentPage {
                    dotImage = self.activeImage
                }
                view.clipsToBounds = false
                view.addSubview(UIImageView(image:dotImage))
                i = i + 1
            }
        }
    }

    fileprivate func imageForSubview(_ view:UIView) -> UIImageView? {
        var dot:UIImageView?

        if let dotImageView = view as? UIImageView {
            dot = dotImageView
        } else {
            for foundView in view.subviews {
                if let imageView = foundView as? UIImageView {
                    dot = imageView
                    break
                }
            }
        }

        return dot
    }
}

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