UIPageControl
Overview
UIPageControl
is a UIKit control in iOS that provides a visual indicator for navigating through a series of pages or content items. It displays a sequence of dots, where each dot represents a page, and the highlighted dot indicates the currently active page. Commonly used with UIScrollView
or other paging interfaces, it allows users to visualize and navigate between pages.
Key Features
- Displays a series of dots to represent pages.
- Highlights the current page with a distinct dot.
- Supports user interaction to switch between pages.
- Customizable appearance, including dot colors and sizes.
- Lightweight and easy to integrate with paging interfaces like
UIScrollView
.
Usage
UIPageControl
is typically used in scenarios where content is divided into multiple pages, such as onboarding screens, image carousels, or tutorials. It can be configured programmatically or via Interface Builder in Xcode.
Basic Setup
To use UIPageControl
, add it to your view hierarchy and configure its properties, such as the number of pages and the current page.
Example: Creating a UIPageControl Programmatically
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Create UIPageControl
let pageControl = UIPageControl()
pageControl.frame = CGRect(x: 50, y: 500, width: 200, height: 20)
pageControl.numberOfPages = 5 // Set total number of pages
pageControl.currentPage = 0 // Set starting page
pageControl.addTarget(self, action: #selector(pageControlTapped(_:)), for: .valueChanged)
// Add to view
view.addSubview(pageControl)
}
@objc func pageControlTapped(_ sender: UIPageControl) {
// Handle page change
print("Current page: \(sender.currentPage)")
}
}
Integration with UIScrollView
UIPageControl
is often paired with a UIScrollView
to create a paging interface. The scroll view handles the content, while the page control provides the visual indicator.
Example: UIPageControl with UIScrollView
import UIKit
class ViewController: UIViewController, UIScrollViewDelegate {
let scrollView = UIScrollView()
let pageControl = UIPageControl()
override func viewDidLoad() {
super.viewDidLoad()
// Setup ScrollView
scrollView.frame = view.bounds
scrollView.isPagingEnabled = true
scrollView.delegate = self
scrollView.contentSize = CGSize(width: view.frame.width * 3, height: view.frame.height)
// Setup PageControl
pageControl.frame = CGRect(x: 50, y: view.frame.height - 50, width: 200, height: 20)
pageControl.numberOfPages = 3
pageControl.currentPage = 0
pageControl.addTarget(self, action: #selector(pageControlTapped(_:)), for: .valueChanged)
// Add to view
view.addSubview(scrollView)
view.addSubview(pageControl)
// Add sample content to scrollView
for i in 0..<3 {
let page = UIView(frame: CGRect(x: view.frame.width * CGFloat(i), y: 0, width: view.frame.width, height: view.frame.height))
page.backgroundColor = [UIColor.red, UIColor.blue, UIColor.green][i]
scrollView.addSubview(page)
}
}
@objc func pageControlTapped(_ sender: UIPageControl) {
// Scroll to selected page
let page = sender.currentPage
let offset = CGPoint(x: scrollView.frame.width * CGFloat(page), y: 0)
scrollView.setContentOffset(offset, animated: true)
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// Update page control based on scroll position
let pageIndex = round(scrollView.contentOffset.x / scrollView.frame.width)
pageControl.currentPage = Int(pageIndex)
}
}
Key Properties
numberOfPages
: Sets the total number of pages (dots) to display.currentPage
: Specifies the currently active page (zero-based index).pageIndicatorTintColor
: Sets the color of inactive page dots.currentPageIndicatorTintColor
: Sets the color of the active page dot.hidesForSinglePage
: Iftrue
, hides the control when there is only one page.defersCurrentPageDisplay
: Iftrue
, delays updating the current page untilupdateCurrentPageDisplay()
is called.
Customization
You can customize the appearance of UIPageControl
to match your app’s design:
Changing Dot Colors
pageControl.pageIndicatorTintColor = UIColor.gray
pageControl.currentPageIndicatorTintColor = UIColor.blue
Hiding for Single Page
pageControl.hidesForSinglePage = true
Custom Dot Images (iOS 14+)
In iOS 14 and later, you can use custom images for page indicators:
pageControl.setIndicatorImage(UIImage(named: "customDot"), forPage: 0)
Accessibility
UIPageControl
supports accessibility by default, but you can enhance it:
- Set
isAccessibilityElement = true
to ensure VoiceOver recognizes it. - Provide an
accessibilityLabel
to describe the control’s purpose, e.g.,"Page indicator for onboarding screens"
. - Use
accessibilityValue
to describe the current page, e.g.,"Page 1 of 5"
.
pageControl.isAccessibilityElement = true
pageControl.accessibilityLabel = "Page indicator"
pageControl.accessibilityValue = "Page \(pageControl.currentPage + 1) of \(pageControl.numberOfPages)"
Limitations
UIPageControl
only provides the visual indicator and user interaction; it does not handle content scrolling or paging logic.- Limited customization for dot size and spacing (some advanced customizations require a custom implementation).
- Custom images for indicators are only available in iOS 14 and later.
Best Practices
- Pair with
UIScrollView
or similar for seamless paging experiences. - Update
currentPage
when the user scrolls to keep the control in sync. - Use distinct colors for active and inactive dots to improve visibility.
- Ensure accessibility support for inclusive user experiences.
- Test on various screen sizes to ensure proper placement and visibility.
Availability
- Available in iOS 2.0 and later.
- Compatible with UIKit-based apps (not SwiftUI, though SwiftUI has its own
PageControl
equivalent).