Add border for dots in UIPageControl
Edited- Swift 3 & 4 extension to achieve the same result-
extension UIPageControl { func customPageControl(dotFillColor:UIColor, dotBorderColor:UIColor, dotBorderWidth:CGFloat) { for (pageIndex, dotView) in self.subviews.enumerated() { if self.currentPage == pageIndex { dotView.backgroundColor = dotFillColor dotView.layer.cornerRadius = dotView.frame.size.height / 2 }else{ dotView.backgroundColor = .clear dotView.layer.cornerRadius = dotView.frame.size.height / 2 dotView.layer.borderColor = dotBorderColor.cgColor dotView.layer.borderWidth = dotBorderWidth } } }}
to use it write below code in viewDidLoad() or viewDidAppear()
pageControl.customPageControl(dotFillColor: .orange, dotBorderColor: .green, dotBorderWidth: 2)
In Objective-C use below code-
- (void) customPageControlWithFillColor:(UIColor*)dotFillColor borderColor:(UIColor*)dotBorderColor borderWidth:(CGFloat)dotBorderWidth { for (int pageIndex = 0; pageIndex < _pageControl.numberOfPages; pageIndex++) { UIView* dotView = [_pageControl.subviews objectAtIndex:pageIndex]; if (_pageControl.currentPage == pageIndex) { dotView.backgroundColor = dotFillColor; dotView.layer.cornerRadius = dotView.frame.size.height / 2; } else { dotView.backgroundColor = [UIColor clearColor]; dotView.layer.cornerRadius = dotView.frame.size.height / 2; dotView.layer.borderColor = dotBorderColor.CGColor; dotView.layer.borderWidth = dotBorderWidth; } }}
Output-
Another approach would be to use a pattern image of the correct size (which currently is 7 points in diameter). Here's what the result looks like:
And here's how it's done:
let image = UIImage.outlinedEllipse(size: CGSize(width: 7.0, height: 7.0), color: .darkGray)self.pageControl.pageIndicatorTintColor = UIColor.init(patternImage: image!)self.pageControl.currentPageIndicatorTintColor = .darkGray
Which uses this simple little extension to UIImage
:
/// An extension to `UIImage` for creating images with shapes.extension UIImage { /// Creates a circular outline image. class func outlinedEllipse(size: CGSize, color: UIColor, lineWidth: CGFloat = 1.0) -> UIImage? { UIGraphicsBeginImageContextWithOptions(size, false, 0.0) guard let context = UIGraphicsGetCurrentContext() else { return nil } context.setStrokeColor(color.cgColor) context.setLineWidth(lineWidth) // Inset the rect to account for the fact that strokes are // centred on the bounds of the shape. let rect = CGRect(origin: .zero, size: size).insetBy(dx: lineWidth * 0.5, dy: lineWidth * 0.5) context.addEllipse(in: rect) context.strokePath() let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image }}
The downside of this is that if the dot size changes in an OS update, the image will look weird as it will be tiled or clipped.
SWIFT 3 Version from @RiosK
func updatePageControl() { for (index, dot) in pageControl.subviews.enumerated() { if index == pageControl.currentPage { dot.backgroundColor = dotColor dot.layer.cornerRadius = dot.frame.size.height / 2; } else { dot.backgroundColor = UIColor.clear dot.layer.cornerRadius = dot.frame.size.height / 2 dot.layer.borderColor = dotColor.cgColor dot.layer.borderWidth = dotBorderWidth } }}