Avinas Udayakumar
Avinas Udayakumar

Reputation: 41

UIPageControl dot border color

I’m unable to set the border color of the page control dot in iOS 14. The following code works with iOS < 14, but not with iOS 14:

for (int i = 0; i < [self.subViews count]; i++) {
    UIView *dot = [self.subViews objectAtIndex:i];
    dot.layer.borderWidth = 1;
    dot.layer.borderColor = [UIColor blueColor].CGColor;
}

UIPageControl tint color is clear. I just want to add the border only. Need a solution for this in Obj-C.

Upvotes: 1

Views: 3350

Answers (3)

Sunny Summer
Sunny Summer

Reputation: 41

The iOS 14 allows setting indicator image with SFSymbol so you're able to use circle.fill and simple circle symbols as dots.

func updateBorderColor() {
if #available(iOS 14.0, *) {
    let smallConfiguration = UIImage.SymbolConfiguration(pointSize: 8.0, weight: .bold)
    let circleFill = UIImage(systemName: "circle.fill", withConfiguration: smallConfiguration)
    let circle = UIImage(systemName: "circle", withConfiguration: smallConfiguration)
    for index in 0..<numberOfPages {
        if index == currentPage {
            setIndicatorImage(circleFill, forPage: index)
        } else {
            setIndicatorImage(circle, forPage: index)
        }
    }
    pageIndicatorTintColor = selectionColor
    } else {
    subviews.enumerated().forEach { index, subview in
        if index != currentPage {
            subview.layer.borderColor = selectionColor.cgColor
            subview.layer.borderWidth = 1
        } else {
            subview.layer.borderWidth = 0
        }
    }
}

Upvotes: 0

Dasoga
Dasoga

Reputation: 5695

Well, I only found this like "solution"

Before (< iOS 14):

Before

After (iOS 14):

enter image description here

if #available(iOS 14.0, *) {
            pageControl.currentPageIndicatorTintColor = .blue // custom color
            pageControl.pageIndicatorTintColor = .blue.withAlphaComponent(0.3)
        } else {
            // Fallback on earlier versions
            for index: Int in 0...3 {
                guard pageControl.subviews.count > index else { return }
                let dot: UIView = pageControl.subviews[index]
                dot.layer.cornerRadius = dot.frame.size.height / 2
                if index == pageControl.currentPage {
                    dot.backgroundColor = .blue                        
                    dot.layer.borderWidth = 0
                } else {
                    dot.backgroundColor = UIColor.clear
                    dot.layer.borderColor = UIColor.blue.cgColor
                    dot.layer.borderWidth = 1
                }
            }
}

Upvotes: 3

zrzka
zrzka

Reputation: 21249

Comments

  • iOS 14 is still beta and any view hierarchy based solution can stop working with the next beta release.
  • It can also stop working in any future iOS release (not beta).
  • You're relying on a private view hierarchy. Apple can change it anytime without any further notice. IOW it belongs to the private API usage category = you're on your own here.

UIPageControl view hierarchy

iOS 13

enter image description here

iOS 14

enter image description here

New API

Even if you update your code to match the new view hierarchy ...

UIView *pageControlContentView = self.pageControl.subviews[0];
UIView *pageControlIndicatorContentView = pageControlContentView.subviews[0];
[pageControlIndicatorContentView.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    obj.layer.borderWidth = 1;
    obj.layer.borderColor = UIColor.blueColor.CGColor;
}];

... you'll get something like this:

enter image description here

iOS 14 introduced new properties and methods you can use:

You can use SF Symbols for example:

UIImage *image = [UIImage systemImageNamed:@"link.circle.fill"];
self.pageControl.preferredIndicatorImage = image;

Then you'll get:

enter image description here

In other words, to be safe, avoid private view hierarchies, use preferredIndicatorImage. You can prepare your own images if you'd like to customize them, etc. But it's a topic for another question. If you'd like to do it programmatically, search for questions like this one.

Since you're using private view hierarchy, learn your tools (Xcode) and start with the Examining the View Hierarchy and Debugging View Hierarchies chapters. You'll be able to find yourself what's the problem next time.

Upvotes: 5

Related Questions