Now it\'s white dots with black background. What about if I want it to be black dots with white backgrounds?
- (NSInteger)presentationCountForPageViewControl
It is possible to customise it through appearance. You can do it in AppDelegate like this.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIPageControl *pageControl = [UIPageControl appearance];
pageControl.pageIndicatorTintColor = [UIColor whiteColor];
pageControl.currentPageIndicatorTintColor = [UIColor blackColor];
pageControl.backgroundColor = [UIColor lightGrayColor];
return YES;
}
If you want to do it just for a certain view controller, replace the pageControl with this instead.
UIPageControl *pageControl = [UIPageControl appearanceWhenContainedIn:[MyViewController class], nil];
UIPageControl *pageControl = [UIPageControl appearanceWhenContainedIn:[MyViewController class], nil];
pageControl.pageIndicatorTintColor = [UIColor whiteColor];
pageControl.currentPageIndicatorTintColor = [UIColor redColor];
pageControl.backgroundColor = [UIColor blackColor];
This will change the appearance just for "MyViewController". If you want to have different colors in different page indicators on the same view you have to create different subviews and customize them individually.
You can recursively search it in your subviews
- (void)findAndConfigurePageControlInView:(UIView *)view
{
for (UIView *subview in view.subviews) {
if ([subview isKindOfClass:[UIPageControl class]]) {
UIPageControl * pageControl = (UIPageControl *)subview;
//customize here
pageControl.hidesForSinglePage = YES;
break;
} else {
[self findAndConfigurePageControlInView:subview];
}
}
}
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController
{
[self findAndConfigurePageControlInView:self.view];
return self.promotionsVCs.count;
}
it works for me
If you use the "auto generated" page indicator created by UIPageViewController, I think that you can't customize it. The only way you could do that is to add an extra PageControl, either the one provided by Apple or a custom one as @Maschel proposed.
You can easily access the UIPageViewController
's pageControl
by defining a computed property like this:
var pageControl: UIPageControl? {
for subview in view.subviews {
if let pageControl = subview as? UIPageControl {
return pageControl
}
}
return nil
}
And then customize it to suite your needs like this:
override func viewDidLoad() {
super.viewDidLoad()
pageControl?.backgroundColor = .white
pageControl?.pageIndicatorTintColor = .red
pageControl?.currentPageIndicatorTintColor = .blue
}
Obvious caveat: if Apple ever decides to change the UIPageViewController
view hierarchy this will stop working.
I don't believe that you can manipulate the UIPageViewController's page control. My solution:
I have a "root" UIViewController that is UIPageViewControllerDelegate and UIPageViewControllerDataSource.
On this root view controller, I have @property (strong, nonatomic) IBOutlet UIPageControl *pageControl
. In the corresponding storyboard nib, I add a UIPageControl, position it, and check "Hides for Single Page". I can also change the colors, if I wish.
Then, I add the following in the root view controller's viewDidLoad: self.pageControl.numberOfPages = [self.features count]
My root view controller also has @property (strong, nonatomic) UIPageViewController *pageViewController
. And in the implementation:
self.pageViewController = [[UIPageViewController alloc]
initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll
navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal
options:nil];
self.pageViewController.delegate = self;
DataViewController *startingViewController = [self viewControllerAtIndex:0 storyboard:self.storyboard];
NSArray *viewControllers = @[startingViewController];
[self.pageViewController setViewControllers:viewControllers
direction:UIPageViewControllerNavigationDirectionForward
animated:NO
completion:NULL];
self.pageViewController.dataSource = self;
[self addChildViewController:self.pageViewController];
[self.view addSubview:self.pageViewController.view];
self.pageViewController.view.frame = CGRectMake(0.0, 0.0, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height + 10.0);
[self.pageViewController didMoveToParentViewController:self];
self.view.gestureRecognizers = self.pageViewController.gestureRecognizers;
(SIDE NOTE: That line that sets the frame makes the height of the UIPageViewController's view exceed the screen size so that the native page control is no longer visible. My app is portrait only, iPhone only, so I got off a bit easy here. If you need to handle rotations, you'll have to find a way to keep that native page control offscreen. I tried using auto layout, but UIPageViewController creates a set of magic views that have a bunch of autolayout mask constraints that I couldn't find a way to override.)
Anyway...then I add an extra UIPageViewController delegate method to change my new, non-native UIPageControl to the currently-selected page:
- (void)pageViewController:(UIPageViewController *)viewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
{
if (!completed){return;}
// Find index of current page
DataViewController *currentViewController = (DataViewController *)[self.pageViewController.viewControllers lastObject];
NSUInteger indexOfCurrentPage = [self indexOfViewController:currentViewController];
self.pageControl.currentPage = indexOfCurrentPage;
}
Not as pretty as I would like, but Apple's API for this class doesn't exactly lend itself to elegance.