3. Uipagecontrol custom style under ios14


3. Uipagecontrol custom style under ios14

1. Overview

First, in IOS 14UIPageControlSeveral new properties and methods are added in

///Represents the current background style and enumerates the values
open var backgroundStyle: UIPageControl.BackgroundStyle
///Read only property, indicating whether it is in discrete interaction or continuous interaction
open var interactionState: UIPageControl.InteractionState { get }
///Indicates whether to start continuous interaction. The default is true
open var allowsContinuousInteraction: Bool
///The indicator style is adjusted uniformly, the default is nil, and the style is dot
open var preferredIndicatorImage: UIImage?
///Get the image corresponding to the page, nil if not set
open func indicatorImage(forPage page: Int) -> UIImage?
///Set the corresponding picture at page
open func setIndicatorImage(_ image: UIImage?, forPage page: Int)

At the same time, a method and a property are discarded

///After calling the displayepdate property, the current indicator is delayed
open var defersCurrentPageDisplay: Bool
///Update indicator
open func updateCurrentPageDisplay()

2. Some new attributes and methods

2.1 preferredIndicatorImage

let control = UIPageControl()
control.numberOfPages = 10
control.frame = CGRect(x: 0, y: 300, width: 350, height: 30)
control.pageIndicatorTintColor = .systemRed
control.currentPageIndicatorTintColor = .systemGreen
if #available(iOS 14.0, *) {
    control.preferredIndicatorImage = UIImage(named:"heart")

preferredIndicatorImageYou can replace the indicator image with any image we want

2.2 setIndicatorImage(UIImage?, forPage: Int)

The image corresponding to any page can be set. If the image is nil, the dot will be displayed

let indicatorImages = ["summy", "cloudy", "rainy", "thunder"]
if #available(iOS 14.0, *) {
    for (idx, imageName) in indicatorImages.enumerated() {
        control.setIndicatorImage(UIImage(named:imageName), forPage: idx)


2.3 custom style

Only simple custom styles can be implemented through several new attributes in IOS 14. To achieve complete customization, you still need to use the previous method. Let’s take a look before thatUIPageControlChanges in hierarchy in IOS 14

3. Uipagecontrol custom style under ios14
[iOS 13]
3. Uipagecontrol custom style under ios14
[iOS 14]

The dot has its originUIViewA view becomes a_UIPageControlContentView_UIPageControlIndicatorContentView_UIPageIndicatorViewCombined view, due to_UIPageIndicatorViewIt’s aUIImageViewSo we can use this view directly to render

if #available(iOS 14.0, *) {
    guard let dotContentView = findIndicatorContentView() else {
    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)

@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

3. Uipagecontrol custom style under ios14
[custom pagecontrol]

3. Code address

Small, big

Recommended Today

Application of tree

Application of tree Storage structure of tree Parental representation (sequential storage) Definition: in each node, the “pointer” (position subscript) pointing to the parents is saved. The root node is fixedly stored in 0, – 1 indicates that there are no parents. Add: add directly without following the logical order. Delete: ① set the pointer to […]