Como posso alterar a cor dos pontos de paginação do UIPageControl?


178

Estou desenvolvendo um aplicativo no qual desejo alterar a cor ou a imagem dos UIPageControlpontos de paginação. Como posso mudá-lo? É possível personalizar UIpageControlno cenário acima?

Respostas:


266

ATUALIZAR:

Esta resposta tem 6 anos e está muito desatualizada, mas ainda está atraindo votos e comentários. Desde o iOS 6.0, você deve usar as propriedades pageIndicatorTintColore currentPageIndicatorTintColorem UIPageControl.

RESPOSTA ORIGINAL:

Encontrei esse problema hoje e decidi escrever minha própria classe de substituição simples.

É um UIView sublassado que usa gráficos principais para renderizar os pontos nas cores que você especificar.

Você usa as propriedades expostas para personalizá-lo e controlá-lo.

Se desejar, você pode registrar um objeto delegado para receber notificações quando o usuário tocar em um dos pequenos pontos da página. Se nenhum representante estiver registrado, a visualização não reagirá ao toque na entrada.

Está completamente fresco no forno, mas parece funcionar. Deixe-me saber se você tiver algum problema com isso.

Melhorias futuras:

  • Redimensione os pontos para ajustar os limites atuais, se houver muitos.
  • Não redesenhe a exibição inteira no drawRect:

Exemplo de uso:

CGRect f = CGRectMake(0, 0, 320, 20); 
PageControl *pageControl = [[[PageControl alloc] initWithFrame:f] autorelease];
pageControl.numberOfPages = 10;
pageControl.currentPage = 5;
pageControl.delegate = self;
[self addSubview:pageControl];

Arquivo de cabeçalho:

//
//  PageControl.h
//
//  Replacement for UIPageControl because that one only supports white dots.
//
//  Created by Morten Heiberg <morten@heiberg.net> on November 1, 2010.
//

#import <UIKit/UIKit.h>

@protocol PageControlDelegate;

@interface PageControl : UIView 
{
@private
    NSInteger _currentPage;
    NSInteger _numberOfPages;
    UIColor *dotColorCurrentPage;
    UIColor *dotColorOtherPage;
    NSObject<PageControlDelegate> *delegate;
    //If ARC use __unsafe_unretained id delegate;
}

// Set these to control the PageControl.
@property (nonatomic) NSInteger currentPage;
@property (nonatomic) NSInteger numberOfPages;

// Customize these as well as the backgroundColor property.
@property (nonatomic, retain) UIColor *dotColorCurrentPage;
@property (nonatomic, retain) UIColor *dotColorOtherPage;

// Optional delegate for callbacks when user taps a page dot.
@property (nonatomic, retain) NSObject<PageControlDelegate> *delegate;

@end

@protocol PageControlDelegate<NSObject>
@optional
- (void)pageControlPageDidChange:(PageControl *)pageControl;
@end

Arquivo de implementação:

//
//  PageControl.m
//
//  Replacement for UIPageControl because that one only supports white dots.
//
//  Created by Morten Heiberg <morten@heiberg.net> on November 1, 2010.
//

#import "PageControl.h"

// Tweak these or make them dynamic.
#define kDotDiameter 7.0
#define kDotSpacer 7.0

@implementation PageControl

@synthesize dotColorCurrentPage;
@synthesize dotColorOtherPage;
@synthesize delegate;

- (NSInteger)currentPage
{
    return _currentPage;
}

- (void)setCurrentPage:(NSInteger)page
{
    _currentPage = MIN(MAX(0, page), _numberOfPages-1);
    [self setNeedsDisplay];
}

- (NSInteger)numberOfPages
{
    return _numberOfPages;
}

- (void)setNumberOfPages:(NSInteger)pages
{
    _numberOfPages = MAX(0, pages);
    _currentPage = MIN(MAX(0, _currentPage), _numberOfPages-1);
    [self setNeedsDisplay];
}

    - (id)initWithFrame:(CGRect)frame
{
    if ((self = [super initWithFrame:frame]))
    {
        // Default colors.
        self.backgroundColor = [UIColor clearColor];
        self.dotColorCurrentPage = [UIColor blackColor];
        self.dotColorOtherPage = [UIColor lightGrayColor];

        UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipedRight:)];
        [swipeRight setDirection:UISwipeGestureRecognizerDirectionRight];
        [self addGestureRecognizer:swipeRight];




        UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipedLeft:)];
        [swipe setDirection:UISwipeGestureRecognizerDirectionLeft];
        [self addGestureRecognizer:swipe];

    }
    return self;
}
-(void) swipedLeft:(UISwipeGestureRecognizer *) recognizer
{
    self.currentPage++;
}
-(void) swipedRight:(UISwipeGestureRecognizer *) recognizer
{
    self.currentPage--;
}

- (void)drawRect:(CGRect)rect 
{
    CGContextRef context = UIGraphicsGetCurrentContext();   
    CGContextSetAllowsAntialiasing(context, true);

    CGRect currentBounds = self.bounds;
    CGFloat dotsWidth = self.numberOfPages*kDotDiameter + MAX(0, self.numberOfPages-1)*kDotSpacer;
    CGFloat x = CGRectGetMidX(currentBounds)-dotsWidth/2;
    CGFloat y = CGRectGetMidY(currentBounds)-kDotDiameter/2;
    for (int i=0; i<_numberOfPages; i++)
    {
        CGRect circleRect = CGRectMake(x, y, kDotDiameter, kDotDiameter);
        if (i == _currentPage)
        {
            CGContextSetFillColorWithColor(context, self.dotColorCurrentPage.CGColor);
        }
        else
        {
            CGContextSetFillColorWithColor(context, self.dotColorOtherPage.CGColor);
        }
        CGContextFillEllipseInRect(context, circleRect);
        x += kDotDiameter + kDotSpacer;
    }
}

- (void)dealloc 
{
    [dotColorCurrentPage release];
    [dotColorOtherPage release];
    [delegate release];
    [super dealloc];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (!self.delegate) return;

    CGPoint touchPoint = [[[event touchesForView:self] anyObject] locationInView:self];

    CGFloat dotSpanX = self.numberOfPages*(kDotDiameter + kDotSpacer);
    CGFloat dotSpanY = kDotDiameter + kDotSpacer;

    CGRect currentBounds = self.bounds;
    CGFloat x = touchPoint.x + dotSpanX/2 - CGRectGetMidX(currentBounds);
    CGFloat y = touchPoint.y + dotSpanY/2 - CGRectGetMidY(currentBounds);

    if ((x<0) || (x>dotSpanX) || (y<0) || (y>dotSpanY)) return;

    self.currentPage = floor(x/(kDotDiameter+kDotSpacer));
    if ([self.delegate respondsToSelector:@selector(pageControlPageDidChange:)])
    {
        [self.delegate pageControlPageDidChange:self];
    }
}

@end

Então, como isso funciona? Estou usando o método pagecontrolPageDidChange e não estou recebendo nada. Eu não pode clicar em qualquer um dos botões
— Adam

Olá Heiberg, usei isso para alterar minha página de scrollview, como você faz isso no seu código? [pageControl1 addTarget: ação própria: @selector (changePage :) forControlEvents: UIControlEventValueChanged];
— Desmond

// Ação para alteração de página no UIPageControl - (void) changePage: (UIPageControl *) control {// int page = pageControl.currentPage; int page = pageControl.currentPage; // atualiza a visualização de rolagem para a página apropriada CGRect frame = scrollview.frame; frame.origin.x = frame.size.width * página; frame.origin.y = 0; [scrollview scrollRectToVisible: quadro animado: SIM]; pageControlUsed = SIM; }
— Desmond

Para executar esse código com o ARC, basta remover o método dealloc, alterar atribuir para fraco e adicionar __weak antes da declaração de propriedade em questão. Muito agradável. Muito obrigado.
— cschuff

substitua NSObject <PageControlDelegate> * delegado por __unsafe_unretained id delegate; no cabeçalho para resolver aviso ARC
— Mihir Mehta

150

No iOS 6, você pode definir a cor da tonalidade de UIPageControl:

Existem 2 novas propriedades:

  • pageIndicatorTintColor
  • currentPageIndicatorTintColor

Você também pode usar a API de aparência para alterar a cor da tonalidade de todos os indicadores de página.

Se você está segmentando o iOS 5, verifique se ele não falha:

if ([pageControl respondsToSelector:@selector(setPageIndicatorTintColor:)]) {
    pageControl.pageIndicatorTintColor = [UIColor whiteColor];
}

E o iOS 5? Como você garante que isso não trava?
— Jjxtra 21/04

41
pageControl.pageIndicatorTintColor = [UIColor redColor];
pageControl.currentPageIndicatorTintColor = [UIColor redColor];

funciona para iOS6


2
Fiquei chateado por precisar subclassificar UIPageControl. Isso fez o truque. Isso deve estar na posição # 1.
— Forrest

Por que uma resposta tão complexa é a mais votada quando isso é literalmente tudo o que você precisa?
— TaylorAllred

23

Caso alguém queira uma versão ARC / moderna (não há necessidade de redefinir propriedades como ivar, no dealloc e funciona com o Interface Builder):

#import <UIKit/UIKit.h>

@protocol PageControlDelegate;

@interface PageControl : UIView 

// Set these to control the PageControl.
@property (nonatomic) NSInteger currentPage;
@property (nonatomic) NSInteger numberOfPages;

// Customize these as well as the backgroundColor property.
@property (nonatomic, strong) UIColor *dotColorCurrentPage;
@property (nonatomic, strong) UIColor *dotColorOtherPage;

// Optional delegate for callbacks when user taps a page dot.
@property (nonatomic, weak) NSObject<PageControlDelegate> *delegate;

@end

@protocol PageControlDelegate<NSObject>
@optional
- (void)pageControlPageDidChange:(PageControl *)pageControl;
@end

PageControl.m:

#import "PageControl.h"


// Tweak these or make them dynamic.
#define kDotDiameter 7.0
#define kDotSpacer 7.0

@implementation PageControl

@synthesize dotColorCurrentPage;
@synthesize dotColorOtherPage;
@synthesize currentPage;
@synthesize numberOfPages;
@synthesize delegate;

- (void)setCurrentPage:(NSInteger)page
{
    currentPage = MIN(MAX(0, page), self.numberOfPages-1);
    [self setNeedsDisplay];
}

- (void)setNumberOfPages:(NSInteger)pages
{
    numberOfPages = MAX(0, pages);
    currentPage = MIN(MAX(0, self.currentPage), numberOfPages-1);
    [self setNeedsDisplay];
}

- (id)initWithFrame:(CGRect)frame 
{
    if (self = [super initWithFrame:frame]) 
    {
        // Default colors.
        self.backgroundColor = [UIColor clearColor];
        self.dotColorCurrentPage = [UIColor blackColor];
        self.dotColorOtherPage = [UIColor lightGrayColor];
    }
    return self;
}

-(id)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super initWithCoder:aDecoder])
    {
        self.dotColorCurrentPage = [UIColor blackColor];
        self.dotColorOtherPage = [UIColor lightGrayColor];
    }
    return self;
}

- (void)drawRect:(CGRect)rect 
{
    CGContextRef context = UIGraphicsGetCurrentContext();   
    CGContextSetAllowsAntialiasing(context, true);

    CGRect currentBounds = self.bounds;
    CGFloat dotsWidth = self.numberOfPages*kDotDiameter + MAX(0, self.numberOfPages-1)*kDotSpacer;
    CGFloat x = CGRectGetMidX(currentBounds)-dotsWidth/2;
    CGFloat y = CGRectGetMidY(currentBounds)-kDotDiameter/2;
    for (int i=0; i<self.numberOfPages; i++)
    {
        CGRect circleRect = CGRectMake(x, y, kDotDiameter, kDotDiameter);
        if (i == self.currentPage)
        {
            CGContextSetFillColorWithColor(context, self.dotColorCurrentPage.CGColor);
        }
        else
        {
            CGContextSetFillColorWithColor(context, self.dotColorOtherPage.CGColor);
        }
        CGContextFillEllipseInRect(context, circleRect);
        x += kDotDiameter + kDotSpacer;
    }
}


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (!self.delegate) return;

    CGPoint touchPoint = [[[event touchesForView:self] anyObject] locationInView:self];

    CGFloat dotSpanX = self.numberOfPages*(kDotDiameter + kDotSpacer);
    CGFloat dotSpanY = kDotDiameter + kDotSpacer;

    CGRect currentBounds = self.bounds;
    CGFloat x = touchPoint.x + dotSpanX/2 - CGRectGetMidX(currentBounds);
    CGFloat y = touchPoint.y + dotSpanY/2 - CGRectGetMidY(currentBounds);

    if ((x<0) || (x>dotSpanX) || (y<0) || (y>dotSpanY)) return;

    self.currentPage = floor(x/(kDotDiameter+kDotSpacer));
    if ([self.delegate respondsToSelector:@selector(pageControlPageDidChange:)])
    {
        [self.delegate pageControlPageDidChange:self];
    }
}

@end

1
Um pequeno complemento para impedir o envio ao delegado se o número da página não for alterado após um toque. NSInteger newPage = floor (x / (kDotDiameter + kDotSpacer)); if (self.currentPage == newPage) retorna;
— theLastNightTrain

15

A resposta fornecida por Heiberg funciona muito bem, no entanto, o controle de página não se comporta exatamente como o da apple.

Se você deseja que o controle de página se comporte como o da apple (sempre aumente a página atual em um se você tocar na segunda metade, caso contrário, diminua em um), tente o seguinte método:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

    CGPoint touchPoint = [[[event touchesForView:self] anyObject] locationInView:self];

    CGRect currentBounds = self.bounds;
    CGFloat x = touchPoint.x - CGRectGetMidX(currentBounds);

    if(x<0 && self.currentPage>=0){
        self.currentPage--;
        [self.delegate pageControlPageDidChange:self]; 
    }
    else if(x>0 && self.currentPage<self.numberOfPages-1){
        self.currentPage++;
        [self.delegate pageControlPageDidChange:self]; 
    }   
}

8

Adicione o seguinte código ao DidFinishLauch no AppDelegate,

UIPageControl *pageControl = [UIPageControl appearance];
pageControl.pageIndicatorTintColor = [UIColor lightGrayColor];
pageControl.currentPageIndicatorTintColor = [UIColor blackColor];
pageControl.backgroundColor = [UIColor whiteColor];

Espero que isso ajude.


6

use isso para codificação

if ([pageControl respondsToSelector:@selector(setPageIndicatorTintColor:)]) {
    pageControl.pageIndicatorTintColor = [UIColor whiteColor];
}

ou no storyboard, você pode alterar o tom da página atual

insira a descrição da imagem aqui


Obrigado ... continue compartilhando :)
— Tirth

6

No Swift, esse código dentro do UIPageViewController está obtendo uma referência ao indicador da página e definindo suas propriedades

override func viewDidLoad() {
    super.viewDidLoad()

    //Creating the proxy
    let pageControl = UIPageControl.appearance()
    //Customizing
    pageControl.pageIndicatorTintColor = UIColor.lightGrayColor()
    pageControl.currentPageIndicatorTintColor = UIColor.darkGrayColor()
    //Setting the background of the view controller so the dots wont be on a black background   
    self.view.backgroundColor = UIColor.whiteColor()
}

UIPageControlnão é o mesmo queUIPageViewController
— jungledev

5

Adicionando respostas existentes, isso pode ser feito como,

insira a descrição da imagem aqui


4

É fácil com o Swift 1.2:

UIPageControl.appearance().pageIndicatorTintColor           = UIColor.lightGrayColor()
UIPageControl.appearance().currentPageIndicatorTintColor    = UIColor.redColor()

3
Isso define globalmente. Se você possui vários UIPageControls no seu aplicativo e precisa de cores diferentes com base na classe, use em UIPageControl.appearanceWhenContainedInInstancesOfClasses([MyClassName.self])vez de UIPageControl.appearance(). Requer iOS 9.
— Jon

4

Você pode corrigi-lo com facilidade, adicionando o seguinte código ao arquivo appdelegate.m no seu didFinishLaunchingWithOptionsmétodo:

UIPageControl *pageControl = [UIPageControl appearance];
pageControl.pageIndicatorTintColor = [UIColor darkGrayColor];
pageControl.currentPageIndicatorTintColor = [UIColor orangeColor];
pageControl.backgroundColor = [UIColor whiteColor]

3

Isso funcionou para mim no iOS 7.

pageControl.pageIndicatorTintColor = [UIColor purpleColor];
pageControl.currentPageIndicatorTintColor = [UIColor magentaColor];

2

Não é possível usar o iPhone SDK do ponto de vista oficial. Você pode fazê-lo usando métodos privados, mas isso será uma barreira para entrar na loja de aplicativos.

A única outra solução segura é criar seu próprio controle de página, o que não deve ser muito difícil, pois o controle de página simplesmente exibe a página exibida no momento em uma exibição de rolagem.


Theere não é um link para minha solução. Minha solução está no texto logo acima do seu comentário. Procure os métodos privados (não saberei o que são) ou escreva seus próprios (não farei isso por você).
— Jasarien

2

@ Jasarien Acho que você pode subclassificar UIPageControll, linha escolhida apenas do documento da apple "As subclasses que personalizam a aparência do controle de página podem usar esse método para redimensionar o controle de página quando a contagem de páginas mudar" para o método sizeForNumberOfPages:


2

Você também pode usar a Biblioteca Three20 que contém um PageControl estilizado e dezenas de outros Controles e Abstrações da UI úteis.


2

No caso de Swift 2.0e para cima, o código abaixo funcionará:

pageControl.pageIndicatorTintColor = UIColor.whiteColor()
pageControl.currentPageIndicatorTintColor = UIColor.redColor()

-1
myView.superview.tintColor = [UIColor colorWithRed:1.0f  
                                      green:1.0f blue:1.0f alpha:1.0f];
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.