28

I am newbie to iphone programming, I am trying to develop an app which uses page control. My view's background color is white and page controllers default one is also white, which makes page control invisible on my view so I have changed the back ground color of page control to make is visible. Now, the view appears patched and bad. Is there a way to change just the dots color for page control?

Thanks in advance

Martin Schröder
  • 4,176
  • 7
  • 47
  • 81
iPhone Programmer
  • 283
  • 1
  • 4
  • 4
  • Duplicate question. BTW, see this http://stackoverflow.com/questions/2942636/how-i-change-the-color-of-pagination-dots-of-uipagecontrol, given solution is one of the best in the world. Personally i used it so many times. – Tirth Jan 21 '13 at 06:49
  • you can refer this post http://stackoverflow.com/questions/26648988/code-to-give-different-color-for-each-pagination-dots-in-ios/26649447#26649447 – Ramesh Muthe Nov 06 '14 at 06:16

10 Answers10

52

We customized the UIPageControl to use a custom image for the page indicator, I have listed the guts of the class below...

GrayPageControl.h

@interface GrayPageControl : UIPageControl
{
    UIImage* activeImage;
    UIImage* inactiveImage;
}

GrayPageControl.m

-(id) initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];

    activeImage = [[UIImage imageNamed:@"active_page_image.png"] retain];
    inactiveImage = [[UIImage imageNamed:@"inactive_page_image.png"] retain];

    return self;
}

-(void) updateDots
{
    for (int i = 0; i < [self.subviews count]; i++)
    {
        UIImageView* dot = [self.subviews objectAtIndex:i];
        if (i == self.currentPage) dot.image = activeImage;
        else dot.image = inactiveImage;
    }
}

-(void) setCurrentPage:(NSInteger)page
{
    [super setCurrentPage:page];
    [self updateDots];
}

Then in the View Controller we just use it like a normal UIPageControl

IBOutlet GrayPageControl* PageIndicator;

Edit:

In the view controller that has the GrayPageControl I have an IBAction that is linked to the GrayPageControl.ValueChanged event.

-(IBAction) pageChanged:(id)sender
{
    int page = PageIndicator.currentPage;

    // update the scroll view to the appropriate page
    CGRect frame = ImagesScroller.frame;
    frame.origin.x = frame.size.width * page;
    frame.origin.y = 0;
    [ImagesScroller scrollRectToVisible:frame animated:YES];
}
JWD
  • 12,188
  • 3
  • 34
  • 32
  • 2
    I also added an override to layoutSubviews that just called updateDots - it removed a slight flicker when the control was first added :) – deanWombourne Nov 22 '10 at 13:23
  • I'm just looking for your solution and can not get it work. I try to connect *PageIndicator to UIPageControl element in Interface Builder with no luck. How can I do that? Thanks! – Borut Tomazin Jun 30 '11 at 07:26
  • It works now. I just set the PageControl class to UIPageControl in Interface Builder. But now I want to make "dots" (images) larger. I have done this in updateDots() method: dot.frame = CGRectMake(0, 0, 20, 20); When I fire up app it is ok. But on scrolling it shows me only one. Is there a solution? – Borut Tomazin Jun 30 '11 at 07:37
  • 2
    I solved the problem: dot.frame = CGRectMake(dot.frame.origin.x, dot.frame.origin.y, 20., 20.); Thanks man, your code is simple, yet awesome! – Borut Tomazin Jun 30 '11 at 07:42
  • The code is more simple and awesome.I got this working.Now my only problem is i want to reduce the space between one dot and the other dot.How can i achieve this? – Sankar Chandra Bose Sep 12 '11 at 00:00
  • edit your code according to memory management. Also the new custom pageControl is blinking. – Gargo Aug 22 '12 at 10:01
  • You should initialize initWithCoder and initWithFrame with some common initialization. – Anonymous White Oct 22 '12 at 00:32
  • 2
    -(void) setCurrentPage:(NSInteger)page isn't called when I clicked the button. – Anonymous White Oct 22 '12 at 00:50
  • 1
    Just to let you know, this crashes on iOS7 (compiling with Xcode 5) as UIPageControl subviews are not UIImageViews any more. – Monitus Sep 25 '13 at 08:33
  • 1
    not working in ios 7. Give exception "Unrecoganised selector" because [self.subviews objectAtIndex:i] returns UIView instead of UIImageview and image is not property of UIView. pLease check and provide some solution to my [Question here](http://stackoverflow.com/questions/19024167/subviews-of-custom-uipageviewcontrol-return-uiview-in-ios7-but-uiimageview-in-io] – Sahil Mahajan Sep 26 '13 at 09:24
18

The application crashes in iOS7. I have a Solution for iOS 7:

Reason for Crash:

in iOS 7 [self.subViews objectAtIndex: i] returns UIView Instead of UIImageView and setImage is not the property of UIView and the app crashes. I solve my problem using this following code.

Check Whether the subview is UIView(for iOS7) or UIImageView(for iOS6 or earlier). And If it is UIView I am going to add UIImageView as subview on that view and voila its working and not crash..!!

-(void) updateDots
{
    for (int i = 0; i < [self.subviews count]; i++)
    {
        UIImageView * dot = [self imageViewForSubview:  [self.subviews objectAtIndex: i]];
        if (i == self.currentPage) dot.image = activeImage;
        else dot.image = inactiveImage;
    }
}
 - (UIImageView *) imageViewForSubview: (UIView *) view
{
    UIImageView * dot = nil;
    if ([view isKindOfClass: [UIView class]])
    {
        for (UIView* subview in view.subviews)
        {
            if ([subview isKindOfClass:[UIImageView class]])
            {
                dot = (UIImageView *)subview;
                break;
            }
        }
        if (dot == nil)
        {
            dot = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, view.frame.size.width, view.frame.size.height)];
            [view addSubview:dot];
        }
    }
    else
    {
        dot = (UIImageView *) view;
    }

    return dot;
}

Hope this solve ur issue too for iOS7. and If Anypone find the optimal solution for that please comment. :)

Happy coding

Sahil Mahajan
  • 3,922
  • 2
  • 29
  • 43
  • If you dont want the white rounded colors on background just add view.backgroundColor = [UIColor clearColor]; in beginning of imageViewForSubview method. – Oleh Kudinov Jun 30 '14 at 14:48
15

JWD answer is the way to go. However, if all you want is to just change the color, why not do this:

This technique will only work on iOS6.0 and higher!

enter image description here

Select your UIPageControl go to attribute inspector. Tada.

Or alternatively you can play around with these 2 properties:

  pageIndicatorTintColor  property
  currentPageIndicatorTintColor  property

This is so simple. I read the question again to make sure I am not wrong. You really just want to change the color don't you? Then yes.

You're still stuck with that lawsy dots. Use JWD technique for the awesome dot pictures.

Hemang
  • 26,840
  • 19
  • 119
  • 186
Anonymous White
  • 2,149
  • 3
  • 20
  • 27
  • I don't want to boast. Though JWD answer is very good, mine is the only one actually answering the question :D – Anonymous White Oct 30 '12 at 10:25
  • if i want to do the same in iOS 5 then what will i do ? – Apple Apr 24 '13 at 09:10
  • i follwed appcoda tutorial for building the uipageview controler in my app. I didn't find any controls that you mentioned above. is these controls still available in x code 6 ? if there pleas help me with some details. Like to change the selected page's dot as blue and others to be back dots -thanks in advance – SARATH SASI Jun 01 '15 at 13:05
7

just one line of code fir your demand. The example set to black color.

pageControl.pageIndicatorTintColor = [UIColor blackColor];
jianpx
  • 3,190
  • 1
  • 30
  • 26
5

DDPageControl is an excellent replacement. Check it out!

You can also view the archived blog post here.

raidfive
  • 6,603
  • 1
  • 35
  • 32
4

You can change the page indicator tint color and the current page indicator tint color with the following code:

pageControl.pageIndicatorTintColor = [UIColor orangeColor];
pageControl.currentPageIndicatorTintColor = [UIColor blackColor];
Alessandro Pirovano
  • 2,509
  • 28
  • 21
3

if you just want to change color of dots or customize it you can make it as recommended by JWD, but in little bit another way:

#pragma mark - LifeCycle

- (void)setCurrentPage:(NSInteger)page
{
    [super setCurrentPage:page];
    [self updateDots];
}

#pragma mark - Private

- (void)updateDots
{
    for (int i = 0; i < [self.subviews count]; i++) {
        UIView* dot = [self.subviews objectAtIndex:i];
        if (i == self.currentPage) {
            dot.backgroundColor = UIColorFromHEX(0x72E7DB);
            dot.layer.cornerRadius = dot.frame.size.height / 2;
        } else {
            dot.backgroundColor = UIColorFromHEX(0xFFFFFF);
            dot.layer.cornerRadius = dot.frame.size.height / 2 - 1;
            dot.layer.borderColor = UIColorFromHEX(0x72E7DB).CGColor;
            dot.layer.borderWidth = 1;
        }
    }
}

As result you will get something like

enter image description here

Also macros:

#define UIColorFromHEX(hexValue) [UIColor colorWithRed:((float)((hexValue & 0xFF0000) >> 16))/255.0 green:((float)((hexValue & 0xFF00) >> 8))/255.0 blue:((float)(hexValue & 0xFF))/255.0 alpha:1.0]
hbk
  • 10,908
  • 11
  • 91
  • 124
2

The best and most siple way to do this is to add the following lines of code in the didFinishLaunchingWithOptions method in the AppDelegate.m

UIPageControl *pageControl = [UIPageControl appearance];
pageControl.pageIndicatorTintColor = [UIColor lightGrayColor];
pageControl.currentPageIndicatorTintColor = [UIColor blackColor];
pageControl.backgroundColor = [UIColor whiteColor];
SteBra
  • 4,188
  • 6
  • 37
  • 68
1

Here is a related answer for using a custom image (if you're flexible and can use an image rather than altering the colors directly).

Customize dot with image of UIPageControl at index 0 of UIPageControl

Community
  • 1
  • 1
CodenameDuchess
  • 1,221
  • 18
  • 24
1

You might wanna have a look on this solution in another stackoverflow question.

Community
  • 1
  • 1
Kai Huppmann
  • 10,705
  • 6
  • 47
  • 78