i'm using UIPageViewController in my app and it's working fine. however, it's page control which has been added automatically has a black background which is hiding the current view controller's bottom material (See picture below). is it possible to call the UIPageViewController's page control and change it's color? i want the page control to be shown over the view controller (example, the Path app's walkthrough) like setting the color instead of black to clear.
-
These may be helpful. http://stackoverflow.com/questions/17684922/changing-uipageviewcontroller-own-pagecontroller-regarding-color-of-dots http://stackoverflow.com/questions/17466718/can-we-customize-the-page-indicator-in-uipageviewcontroller – Stu P. Aug 23 '13 at 17:20
9 Answers
You can use appearance
to change the color of UIPageControl as otherwise it is not accessible. Try doing it in your AppDelegate's didFinishLaunchingWithOptions
function as given below.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIPageControl *pageControl = [UIPageControl appearance];
pageControl.pageIndicatorTintColor = [UIColor lightGrayColor];
pageControl.currentPageIndicatorTintColor = [UIColor blackColor];
pageControl.backgroundColor = [UIColor blueColor];
return YES;
}
To apply style only to a particular view controller, you can use appearanceWhenContainedIn
instead as following:
UIPageControl *pageControl = [UIPageControl appearanceWhenContainedIn:[MyViewController class], nil];
Only UIPageControl
objects contained in the MyViewController
are going to get this style.
EDIT:
The black background around UIPageControl
at the bottom of your screen is due to the background color of your UIPageViewController
not UIPageControl
. You can change this color as following:
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor blueColor]; //Set it to whatever you like
}

- 10,517
- 9
- 48
- 53
-
2thank you but it actually couldn't make it transparent so that i can show what's under it ([uicolor clearcolor]). however, it's a valuable piece of information. i got a question and hope you give me more info on. how does it know which pageControl i'm targeting ? how does the appearance work? Thank you so much! – user1938695 Aug 23 '13 at 18:23
-
@user1938695 If you want it to be transparent, take the last line of his code and change it to read: `pageControl.backgroundColor = [[UIColor blueColor] colorWithAlphaComponent:0.5f];` – BrianS Jan 24 '14 at 05:55
-
This gets me close but I'm still unable to get the background to be transparent. – Pork 'n' Bunny Feb 10 '14 at 04:24
-
@Pork'n'Bunny - is `pageControl.backgroundColor = [UIColor clearColor];` not working for you? – Yas Tabasam Feb 10 '14 at 06:02
-
-
Yeah, it's UIPageViewController. It looks the same as the screenshot in the OP question even after setting the backgroundColor of the pageControl to clearColor or even a different color and changing the alpha. Its certainly not what I expect... Your code definitely changes the attributes of the relevant elements. So I can change the color fine, but clearColor results in black. – Pork 'n' Bunny Feb 12 '14 at 18:57
-
3This is happening due to your `UIPageControllerView` view having no color which essentially shows as black. Add this to your `UIPageViewController`'s `viewDidLoad:` function to change black color to red. `self.view.backgroundColor = [UIColor redColor];` – Yas Tabasam Feb 13 '14 at 21:50
-
Hmmm ... the thing with this setting of backgroundColor is that apparently the size of the page control is always the original size, it doesn't change when more page bullets are added - which leads to a strange result. – TheEye Mar 14 '14 at 09:53
Updated for Swift 3:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
for view in self.view.subviews {
if view is UIScrollView {
view.frame = UIScreen.main.bounds
} else if view is UIPageControl {
view.backgroundColor = UIColor.clear
}
}
}
Swift 2 example for anyone that needs it. Put this inside your UIPageController subclass.
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
for view in self.view.subviews {
if view is UIScrollView {
view.frame = UIScreen.mainScreen().bounds
} else if view is UIPageControl {
view.backgroundColor = UIColor.clearColor()
}
}
}

- 7,932
- 11
- 44
- 64

- 867
- 9
- 7
-
Hi @Imran - the objC code from orkenstein above is essentially the same. I was just providing a swift example here for others. – jlichti Feb 09 '16 at 09:11
-
What part is not working? I can't help unless you explain your problem a bit better. You could also just port this code to ObjC pretty easily too. – jlichti Feb 09 '16 at 13:45
-
1For me it works. I just changed view.frame = UIScreen.mainScreen().bounds into view.frame = self.view.bounds – Jan Doornbos May 27 '16 at 09:55
-
For me this swift version works but it also sets the page controller indicators to clear as well... is there a way I can show the indicators? or change their colours? – Agustin Jun 28 '16 at 01:06
-
It worked for me on Swift 3.0 / XCode 8.3. iOS 10.3.1. I had to add this method in the "UIPageViewController". Added it in a hurry by mistake in my ContentViewController. – Darkwonder May 16 '17 at 07:34
-
This is perfect. Thanks for the easy solution and non-hacky way of doing it. – Scott D May 18 '17 at 18:40
Add the following code in the UIPageViewController.
- (void)viewDidLoad {
[super viewDidLoad];
[[UIPageControl appearance] setPageIndicatorTintColor: [UIColor grayColor]];
[[UIPageControl appearance] setCurrentPageIndicatorTintColor: [UIColor whiteColor]];
[[UIPageControl appearance] setBackgroundColor: [UIColor darkGrayColor]];
}

- 2,380
- 1
- 15
- 6
Just subclass UIPageViewController and add this code:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
for (UIView *view in self.view.subviews) {
if ([view isKindOfClass:[NSClassFromString(@"_UIQueuingScrollView") class]]) {
CGRect frame = view.frame;
frame.size.height = view.superview.frame.size.height;
view.frame = frame;
}
}
}
This will extend internal scroll view frame.

- 2,810
- 3
- 24
- 45
-
3Had to add [self.view sendSubviewToBack:view]; within the if statement for it to work properly here. – Matthijn Mar 20 '15 at 16:11
-
This makes my view "jump" when I tap on it to scroll to the next page. I have no idea how to fix this. – TheJeff Aug 30 '16 at 01:02
-
2
Here is the Swift 2+ version of Yas-T's Answer
//In AppDelegate
let pageControl = UIPageControl.appearance()
pageControl.pageIndicatorTintColor = UIColor.lightGrayColor()
pageControl.currentPageIndicatorTintColor = UIColor.blackColor()
pageControl.backgroundColor = UIColor.blueColor()
//Or in your ViewController (Only available on IOS 9.0)
if #available(iOS 9.0, *) {
let pageControl = UIPageControl.appearanceWhenContainedInInstancesOfClasses([ViewController.self])
pageControl.pageIndicatorTintColor = UIColor.lightGrayColor()
pageControl.currentPageIndicatorTintColor = UIColor.darkGrayColor()
}

- 1
- 1

- 2,777
- 28
- 24
Here is the Swift 3+ version of accepted Answer (with a plus of a custom Color created):
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if #available(iOS 9.0, *) {
let pageControl = UIPageControl.appearance(whenContainedInInstancesOf: [UIPageViewController.self])
pageControl.pageIndicatorTintColor = UIColor.init(colorLiteralRed: 43/255.0, green: 170/255.0, blue: 226/255.0, alpha: 0.4)
pageControl.currentPageIndicatorTintColor = UIColor.init(colorLiteralRed: 43/255.0, green: 170/255.0, blue: 226/255.0, alpha: 1.0)
}
return true
}

- 271
- 2
- 4
- 18
Override the function viewDidLayoutSubviews()
in PageViewController:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
for view in view.subviews{
if view is UIScrollView{
view.frame = UIScreen.main.bounds
}else if view is UIPageControl{
view.backgroundColor = UIColor.clear
}
}
}

- 4,444
- 9
- 45
- 69

- 150
- 4
Well, I found a working solution. Inside your UIPageViewController, just add this code:
-(void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
for (UIView *view in self.view.subviews)
{
if ([view isKindOfClass:UIScrollView.class])
{
CGRect frame = view.frame;
frame.size.height = view.superview.frame.size.height;
view.frame = frame;
}
if ([view isKindOfClass:UIPageControl.class])
{
CGFloat newHeight = 22;
CGRect frame = view.frame;
frame.origin.y += frame.size.height - newHeight;
frame.size.height = newHeight;
view.frame = frame;
view.backgroundColor = UIColor.darkGrayColor;
view.alpha = 0.3;
}
}
}

- 1
- 1
- 2
See my setup method's code in which I change page view controller's page control color and it's worked for me.
private func setupPageController() {
self.pageController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
self.pageController?.dataSource = self
self.pageController?.delegate = self
self.pageController?.view.backgroundColor = .clear
self.pageController?.view.frame = CGRect(x: 0,y: 0,width: self.view.frame.width,height: self.view.frame.height)
self.addChild(self.pageController!)
self.view.addSubview(self.pageController!.view)
for item in self.pageController?.view?.subviews ?? []{
if item is UIPageControl{
(item as! UIPageControl).pageIndicatorTintColor = #colorLiteral(red: 0.501960814, green: 0.501960814, blue: 0.501960814, alpha: 1)
(item as! UIPageControl).currentPageIndicatorTintColor = #colorLiteral(red: 1, green: 0.7489039302, blue: 0, alpha: 1)
break
}
}
let initialVC = strBoard.instantiateViewController(withIdentifier: "TutorialOneVC")
self.pageController?.setViewControllers([initialVC], direction: .forward, animated: true, completion: nil)
self.pageController?.didMove(toParent: self)
}

- 11,356
- 9
- 22
- 40

- 36
- 1
- 5