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?

Tirth
fonte

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 <[email protected]> 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 <[email protected]> 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
Heiberg
fonte
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];
}
Felix
fonte
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

Add080bbA
fonte
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
Ben G
fonte
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]; 
    }   
}
ChristophK
fonte
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.

posha
fonte
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

Pooja Patel
fonte
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()
}
arbel03
fonte
UIPageControlnão é o mesmo queUIPageViewController
jungledev
5

Adicionando respostas existentes, isso pode ser feito como,

insira a descrição da imagem aqui

A a Z
fonte
4

É fácil com o Swift 1.2:

UIPageControl.appearance().pageIndicatorTintColor           = UIColor.lightGrayColor()
UIPageControl.appearance().currentPageIndicatorTintColor    = UIColor.redColor()
Oleg Popov
fonte
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]
Nabil El Atlas
fonte
3

Isso funcionou para mim no iOS 7.

pageControl.pageIndicatorTintColor = [UIColor purpleColor];
pageControl.currentPageIndicatorTintColor = [UIColor magentaColor];
Sid
fonte
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.

Jasarien
fonte
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:

dsaw
fonte
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.

cschuff
fonte
2

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

pageControl.pageIndicatorTintColor = UIColor.whiteColor()
pageControl.currentPageIndicatorTintColor = UIColor.redColor()
Sohil R. Memon
fonte
-1
myView.superview.tintColor = [UIColor colorWithRed:1.0f  
                                      green:1.0f blue:1.0f alpha:1.0f];
Michael Belanger
fonte