Reputation: 5
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
}
}
Upvotes: 0
Views: 1078
Reputation: 1
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
}
}
Upvotes: 0