¿Cómo puedo cambiar el color de los puntos de paginación de UIPageControl?

178

Estoy desarrollando una aplicación en la que quiero cambiar el color o la imagen de los UIPageControlpuntos de paginación. ¿Cómo puedo cambiarlo? ¿Es posible personalizar UIpageControlen el escenario anterior?

Tirth
fuente

Respuestas:

266

ACTUALIZAR:

Esta respuesta tiene 6 años y está muy desactualizada, pero sigue atrayendo votos y comentarios. Desde iOS 6.0 deberías usar las propiedades pageIndicatorTintColory .currentPageIndicatorTintColorUIPageControl

RESPUESTA ORIGINAL:

Me encontré con este problema hoy y decidí escribir mi propia clase de reemplazo simple.

Es una UIView subclase que usa Core Graphics para representar los puntos en los colores que especifique.

Utiliza las propiedades expuestas para personalizarlo y controlarlo.

Si lo desea, puede registrar un objeto delegado para recibir notificaciones cuando el usuario toca uno de los pequeños puntos de página. Si no hay un delegado registrado, la vista no reaccionará a la entrada táctil.

Está completamente recién salido del horno, pero parece funcionar. Avísame si tienes algún problema con él.

Mejoras futuras:

  • Cambie el tamaño de los puntos para que se ajusten a los límites actuales si hay demasiados.
  • No vuelva a dibujar toda la vista en drawRect:

Ejemplo 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];

Archivo de cabecera:

//
//  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

Archivo de implementación:

//
//  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
fuente
Entonces, ¿cómo funciona esto? Estoy usando el método pagecontrolPageDidChange y no obtengo nada. No puedo hacer clic en ninguno de los botones
Adam
Hola Heiberg, usé esto para cambiar mi página de vista de desplazamiento, ¿cómo lo hace desde su código? [pageControl1 addTarget: self action: @selector (changePage :) forControlEvents: UIControlEventValueChanged];
Desmond
// Acción para el cambio de página en UIPageControl - (void) changePage: (UIPageControl *) control {// int page = pageControl.currentPage; int página = pageControl.currentPage; // actualiza la vista de desplazamiento a la página apropiada CGRect frame = scrollview.frame; frame.origin.x = frame.size.width * página; frame.origin.y = 0; [scrollview scrollRectToVisible: marco animado: SÍ]; pageControlUsed = YES; }
Desmond
Para ejecutar este código con ARC, simplemente deberá eliminar el método dealloc, cambiar la asignación a débil y agregar un __weak antes de la declaración de propiedad en cuestión. Muy agradable. Muchas gracias.
cschuff 01 de
reemplace NSObject <PageControlDelegate> * delegate con __unsafe_unretained id delegate; en el encabezado para resolver la advertencia de ARC
Mihir Mehta
150

En iOS 6 puede configurar el color de tinte de UIPageControl:

Hay 2 nuevas propiedades:

  • pageIndicatorTintColor
  • currentPageIndicatorTintColor

También puede usar la API de apariencia para cambiar el color de tinte de todos los indicadores de página.

Si está apuntando a iOS 5, asegúrese de que no se bloquee:

if ([pageControl respondsToSelector:@selector(setPageIndicatorTintColor:)]) {
    pageControl.pageIndicatorTintColor = [UIColor whiteColor];
}
Felix
fuente
¿Qué pasa con iOS 5? ¿Cómo te aseguras de que esto no se bloquee?
jjxtra
41
pageControl.pageIndicatorTintColor = [UIColor redColor];
pageControl.currentPageIndicatorTintColor = [UIColor redColor];

funciona para iOS6

Add080bbA
fuente
2
Me desanimó que iba a necesitar subclasificar UIPageControl. Esto hizo el truco. Esto debería estar en la posición # 1.
Forrest
¿Por qué una respuesta tan compleja es la más votada cuando esto es literalmente todo lo que necesitas?
TaylorAllred
23

En caso de que alguien quiera una versión ARC / moderna (no es necesario redefinir las propiedades como ivar, no dealloc y funciona con 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
fuente
1
Una pequeña adición para evitar que se envíe al delegado si el número de página en realidad no cambió después de un toque. NSInteger newPage = floor (x / (kDotDiameter + kDotSpacer)); if (self.currentPage == newPage) return;
theLastNightTrain
15

La respuesta proporcionada por Heiberg funciona muy bien, sin embargo, el control de la página no se comporta exactamente como el de Apple.

Si desea que el control de la página se comporte como lo hace el de Apple (siempre incremente la página actual en uno si toca la segunda mitad, de lo contrario, disminuya en uno), intente con este método touchBegan:

- (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
fuente
8

Agregue el siguiente código a DidFinishLauch en AppDelegate,

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

Espero que esto ayude.

posha
fuente
6

use esto para codificar

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

o desde el guión gráfico puede cambiar el tinte de la página actual

ingrese la descripción de la imagen aquí

Pooja Patel
fuente
Gracias ... sigan compartiendo :)
Tirth
6

En Swift, este código dentro del UIPageViewController obtiene una referencia al indicador de página y establece sus propiedades

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
fuente
UIPageControlno es lo mismo queUIPageViewController
jungledev
5

Agregando a las respuestas existentes, se puede hacer como,

ingrese la descripción de la imagen aquí

de la A a la Z
fuente
4

Es fácil con Swift 1.2:

UIPageControl.appearance().pageIndicatorTintColor           = UIColor.lightGrayColor()
UIPageControl.appearance().currentPageIndicatorTintColor    = UIColor.redColor()
Oleg Popov
fuente
3
Esto lo establece a nivel mundial. Si tiene varios UIPageControls en su aplicación y necesita diferentes colores según la clase, use en UIPageControl.appearanceWhenContainedInInstancesOfClasses([MyClassName.self])lugar de UIPageControl.appearance(). Requiere iOS 9.
Jon
4

Puede solucionarlo fácilmente agregando el siguiente código a su archivo appdelegate.m en su didFinishLaunchingWithOptionsmétodo:

UIPageControl *pageControl = [UIPageControl appearance];
pageControl.pageIndicatorTintColor = [UIColor darkGrayColor];
pageControl.currentPageIndicatorTintColor = [UIColor orangeColor];
pageControl.backgroundColor = [UIColor whiteColor]
Nabil El Atlas
fuente
3

Esto me funcionó en iOS 7.

pageControl.pageIndicatorTintColor = [UIColor purpleColor];
pageControl.currentPageIndicatorTintColor = [UIColor magentaColor];
Sid
fuente
2

No es posible usar el SDK de iPhone desde un punto de vista oficial. Es posible que pueda hacerlo utilizando métodos privados, pero eso será una barrera para acceder a la tienda de aplicaciones.

La única otra solución segura es crear su propio control de página que no debe ser demasiado difícil dado que el control de página simplemente muestra qué página se muestra actualmente en una vista de desplazamiento.

Jasarien
fuente
No hay un enlace a mi solución. Mi solución está en el texto justo arriba de tu comentario. Busque los métodos privados (no sabré cuáles son) o escriba los suyos (no voy a hacer eso por usted).
Jasarien
2

@Jasarien Creo que puede subclasificar UIPageControll, línea seleccionada solo de Apple doc "Las subclases que personalizan la apariencia del control de página pueden usar este método para cambiar el tamaño del control de página cuando el recuento de páginas cambia" para el método sizeForNumberOfPages:

dsaw
fuente
2

También puede usar la biblioteca Three20 que contiene un control de página con estilo y docenas de otros controles y abstracciones de interfaz de usuario útiles.

cschuff
fuente
2

En mayúsculas Swift 2.0y minúsculas, el siguiente código funcionará:

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