Come posso cambiare il colore dei punti di impaginazione di UIPageControl?


178

Sto sviluppando un'applicazione in cui desidero cambiare il colore o l'immagine dei UIPageControlpunti di impaginazione. Come posso cambiarlo? È possibile personalizzare UIpageControlsullo scenario sopra?

Risposte:


266

AGGIORNARE:

Questa risposta ha 6 anni ed è molto obsoleta, ma sta ancora attirando voti e commenti. Da iOS 6.0 dovresti usare le proprietà pageIndicatorTintColore currentPageIndicatorTintColorsu UIPageControl.

RISPOSTA ORIGINALE:

Ho riscontrato questo problema oggi e ho deciso di scrivere la mia semplice classe di sostituzione.

È una UIView sottoclasse che utilizza Core Graphics per eseguire il rendering dei punti nei colori specificati.

Utilizzare le proprietà esposte per personalizzarlo e controllarlo.

Se lo desideri, puoi registrare un oggetto delegato per ricevere notifiche quando l'utente tocca uno dei piccoli punti della pagina. Se nessun delegato è registrato, la vista non reagirà all'input tattile.

È completamente fresco dal forno, ma sembra funzionare. Fammi sapere se riscontri problemi.

Miglioramenti futuri:

  • Ridimensiona i punti per adattarli ai limiti attuali se ce ne sono troppi.
  • Non ridisegnare l'intera vista in drawRect:

Esempio di utilizzo:

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

File di intestazione:

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

File di implementazione:

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

Quindi come funziona? Sto usando il metodo pagecontrolPageDidChange e non ottengo nulla. Non posso fare clic su nessuno dei pulsanti
Adam,

Ciao Heiberg, l'ho usato per cambiare la mia pagina di scrollview, come fai dal tuo codice? [pageControl1 addTarget: self action: @selector (changePage :) forControlEvents: UIControlEventValueChanged];
Desmond,

// Azione per cambiare pagina su UIPageControl - (void) changePage: (UIPageControl *) control {// int page = pageControl.currentPage; int page = pageControl.currentPage; // aggiorna la vista di scorrimento alla pagina appropriata CGRect frame = scrollview.frame; frame.origin.x = frame.size.width * page; frame.origin.y = 0; [scrollview scrollRectToVisible: frame animato: YES]; pageControlUsed = YES; }
Desmond,

Per eseguire questo codice con ARC dovrai semplicemente rimuovere il metodo dealloc, cambiare assegnazione in debole e aggiungere un __weak prima della relativa dichiarazione di proprietà. Molto bella. Molte grazie.
cschuff

sostituire NSObject <PageControlDelegate> * delegato con __unsafe_unretained id delegate; nell'intestazione per risolvere l'avvertimento ARC
Mihir Mehta,

150

In iOS 6 puoi impostare il colore della tinta di UIPageControl:

Ci sono 2 nuove proprietà:

  • pageIndicatorTintColor
  • currentPageIndicatorTintColor

Puoi anche utilizzare l'API dell'aspetto per modificare il colore della tinta di tutti gli indicatori di pagina.

Se scegli come target iOS 5 assicurati che non si blocchi:

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

Che dire di iOS 5? Come fai ad assicurarti che non si blocchi?
jjxtra,

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

funziona per iOS6


2
Mi è dispiaciuto che avrei dovuto sottoclassare UIPageControl. Questo ha funzionato. Questo dovrebbe essere nella posizione # 1.
Forrest,

Perché una risposta così complessa è la prima votata quando questa è letteralmente tutto ciò di cui hai bisogno?
Taylor Allred,

23

Nel caso in cui qualcuno desideri una versione ARC / moderna (non è necessario ridefinire le proprietà come ivar, no dealloc e funziona 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

1
Un'aggiunta minore per interrompere l'invio al delegato se il numero di pagina in realtà non è cambiato dopo un tocco. NSInteger newPage = floor (x / (kDotDiameter + kDotSpacer)); if (self.currentPage == newPage) restituisce;
theLastNightTrain

15

La risposta fornita da Heiberg funziona davvero bene, tuttavia il controllo della pagina non si comporta esattamente come quello di Apple.

Se vuoi che il controllo della pagina si comporti come quello di Apple (incrementa sempre la pagina corrente di uno se tocchi la seconda metà, altrimenti diminuisci di uno), prova invece a toccare Metodo -Ban:

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

Aggiungi il seguente codice a DidFinishLauch in AppDelegate,

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

Spero che questo possa aiutare.


6

usalo per codificare

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

o dallo storyboard puoi cambiare dalla tinta della pagina corrente

inserisci qui la descrizione dell'immagine


Grazie ... continua a condividere :)
Tirth,

6

In Swift, questo codice all'interno di UIPageViewController sta ottenendo un riferimento all'indicatore di pagina e impostandone le proprietà

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()
}

UIPageControlnon è lo stesso diUIPageViewController
jungledev,


4

È facile con Swift 1.2:

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

3
Questo lo imposta a livello globale. Se hai più UIPageControls nella tua app e hai bisogno di colori diversi in base alla classe, usa UIPageControl.appearanceWhenContainedInInstancesOfClasses([MyClassName.self])invece di UIPageControl.appearance(). Richiede iOS 9.
Jon

4

Puoi risolverlo facilmente aggiungendo il seguente codice al tuo file appdelegate.m nel tuo didFinishLaunchingWithOptionsmetodo:

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

3

Questo ha funzionato per me in iOS 7.

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

2

Non è possibile utilizzare iPhone SDK da un punto di vista ufficiale. Potresti essere in grado di farlo utilizzando metodi privati, ma ciò costituirà una barriera per accedere all'app store.

L'unica altra soluzione sicura è quella di creare il proprio controllo di pagina che non potrebbe essere troppo difficile dato che il controllo di pagina mostra semplicemente quale pagina è attualmente mostrata in una vista di scorrimento.


Non c'è un collegamento alla mia soluzione. La mia soluzione è lì nel testo appena sopra il tuo commento. O cerca i metodi privati ​​(non saprò cosa sono) o scrivi il tuo (non lo farò per te).
Jasarien,

2

@Jasarien Penso che tu possa sottoclassare UIPageControll, riga scelta solo da apple doc "Le sottoclassi che personalizzano l'aspetto del controllo della pagina possono usare questo metodo per ridimensionare il controllo della pagina quando cambia il conteggio delle pagine" per il metodo sizeForNumberOfPages:


2

È inoltre possibile utilizzare la libreria Three20 che contiene un PageControl personalizzabile e dozzine di altri utili controlli e astrazioni dell'interfaccia utente.


2

In maiuscolo Swift 2.0e minuscolo , il codice seguente funziona:

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];
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.