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.
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
}
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()
}
}
}
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]];
}
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.
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()
}
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
}
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;
}
}
}
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)
}