Comment puis-je changer la couleur des points de pagination d'UIPageControl?

183

Je développe une application dans laquelle je souhaite changer la couleur ou l'image des UIPageControlpoints de pagination. Comment puis-je le changer? Est-il possible de personnaliser UIpageControlle scénario ci-dessus?

Tirth
la source

Réponses:

270

MISE À JOUR:

Cette réponse a 6 ans et est très dépassée, mais elle continue d'attirer des votes et des commentaires. Depuis iOS 6.0, vous devriez utiliser les propriétés pageIndicatorTintColoret currentPageIndicatorTintColorsur UIPageControl.

RÉPONSE ORIGINALE:

J'ai rencontré ce problème aujourd'hui et j'ai décidé d'écrire ma propre classe de remplacement simple.

C'est un UIView sous-classé qui utilise Core Graphics pour rendre les points dans les couleurs que vous spécifiez.

Vous utilisez les propriétés exposées pour le personnaliser et le contrôler.

Si vous le souhaitez, vous pouvez enregistrer un objet délégué pour recevoir des notifications lorsque l'utilisateur appuie sur l'un des petits points de la page. Si aucun délégué n'est enregistré, la vue ne réagira pas à la saisie tactile.

Il est complètement frais du four, mais semble fonctionner. Faites-moi savoir si vous rencontrez des problèmes avec celui-ci.

Améliorations futures:

  • Redimensionnez les points pour qu'ils correspondent aux limites actuelles s'il y en a trop.
  • Ne redessinez pas la vue entière dans drawRect:

Exemple d'utilisation:

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

En tête de fichier:

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

Dossier d'implémentation:

//
//  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
la source
Alors, comment ça marche? J'utilise la méthode pagecontrolPageDidChange et je n'obtiens rien. Je ne peux cliquer sur aucun des boutons
Adam
HI Heiberg, j'ai utilisé ceci pour changer ma page de scrollview, comment faites-vous cela à partir de votre code? [pageControl1 addTarget: auto-action: @selector (changePage :) forControlEvents: UIControlEventValueChanged];
Desmond
// Action de changement de page sur UIPageControl - (void) changePage: (UIPageControl *) control {// int page = pageControl.currentPage; int page = pageControl.currentPage; // met à jour la vue de défilement vers la page appropriée CGRect frame = scrollview.frame; frame.origin.x = frame.size.width * page; frame.origin.y = 0; [scrollview scrollRectToVisible: cadre animé: OUI]; pageControlUsed = OUI; }
Desmond
Pour exécuter ce code avec ARC, vous devrez simplement supprimer la méthode dealloc, changer assign en faible et ajouter un __weak avant la déclaration de propriété concernée. Très agréable. Merci beaucoup.
cschuff
remplacer le délégué NSObject <PageControlDelegate> * par le délégué id __unsafe_unretained; dans l'en-tête pour résoudre l'avertissement ARC
Mihir Mehta
151

Dans iOS 6, vous pouvez définir la couleur de teinte de UIPageControl:

Il y a 2 nouvelles propriétés:

  • pageIndicatorTintColor
  • currentPageIndicatorTintColor

Vous pouvez également utiliser l'API d'apparence pour modifier la couleur de teinte de tous les indicateurs de page.

Si vous ciblez iOS 5, assurez-vous qu'il ne plante pas:

if ([pageControl respondsToSelector:@selector(setPageIndicatorTintColor:)]) {
    pageControl.pageIndicatorTintColor = [UIColor whiteColor];
}
Félix
la source
Et iOS 5? Comment vous assurez-vous que cela ne plante pas?
jjxtra
43
pageControl.pageIndicatorTintColor = [UIColor redColor];
pageControl.currentPageIndicatorTintColor = [UIColor redColor];

fonctionne pour iOS6

Ajouter080bbA
la source
2
J'étais déçu de devoir sous-classer UIPageControl. Cela a fait l'affaire. Cela devrait être à la position n ° 1.
Forrest
Pourquoi une réponse aussi complexe est-elle la plus votée alors que c'est littéralement tout ce dont vous avez besoin?
TaylorAllred
23

Au cas où quelqu'un voudrait une version ARC / moderne de celui-ci (pas besoin de redéfinir les propriétés comme ivar, pas de dealloc et fonctionne avec 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
la source
1
Un ajout mineur pour arrêter l'envoi au délégué si le numéro de page n'a pas réellement changé après une pression. NSInteger newPage = floor (x / (kDotDiameter + kDotSpacer)); if (self.currentPage == newPage) return;
theLastNightTrain
15

La réponse fournie par Heiberg fonctionne très bien, mais le contrôle de page ne se comporte pas exactement comme celui d'Apple.

Si vous voulez que le contrôle de page se comporte comme celui d'Apple (incrémentez toujours la page actuelle de un si vous touchez la seconde moitié, sinon diminuez-le de un), essayez plutôt cette méthode touchesBegan:

- (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
la source
8

Ajoutez le code suivant à DidFinishLauch dans AppDelegate,

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

J'espère que cela aidera.

posha
la source
6

utilisez ceci pour le codage

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

ou à partir du storyboard, vous pouvez changer la teinte de la page actuelle

entrez la description de l'image ici

Pooja Patel
la source
Merci ... continuez à partager :)
Tirth
6

Dans Swift, ce code à l'intérieur de UIPageViewController obtient une référence à l'indicateur de page et définit ses propriétés

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
la source
UIPageControln'est pas le même queUIPageViewController
jungledev
5

En ajoutant aux réponses existantes, cela peut être fait comme,

entrez la description de l'image ici

de A à Z
la source
4

Cela fonctionne pour moi dans iOS 7.

pageControl.pageIndicatorTintColor = [UIColor purpleColor];
pageControl.currentPageIndicatorTintColor = [UIColor magentaColor];
Sid
la source
4

C'est facile avec Swift 1.2:

UIPageControl.appearance().pageIndicatorTintColor           = UIColor.lightGrayColor()
UIPageControl.appearance().currentPageIndicatorTintColor    = UIColor.redColor()
Oleg Popov
la source
3
Cela le définit globalement. Si vous avez plusieurs UIPageControls dans votre application et que vous avez besoin de couleurs différentes en fonction de la classe, utilisez à la UIPageControl.appearanceWhenContainedInInstancesOfClasses([MyClassName.self])place de UIPageControl.appearance(). Nécessite iOS 9.
Jon
4

Vous pouvez le résoudre facilement en ajoutant le code suivant à votre fichier appdelegate.m dans votre didFinishLaunchingWithOptionsméthode:

UIPageControl *pageControl = [UIPageControl appearance];
pageControl.pageIndicatorTintColor = [UIColor darkGrayColor];
pageControl.currentPageIndicatorTintColor = [UIColor orangeColor];
pageControl.backgroundColor = [UIColor whiteColor]
Nabil El Atlas
la source
2

@Jasarien Je pense que vous pouvez sous-classer UIPageControll, ligne choisie uniquement dans le document Apple "Les sous-classes qui personnalisent l'apparence du contrôle de page peuvent utiliser cette méthode pour redimensionner le contrôle de page lorsque le nombre de pages change" pour la méthode sizeForNumberOfPages:

dsaw
la source
2

Vous pouvez également utiliser la bibliothèque Three20 qui contient un PageControl stylable et des dizaines d'autres contrôles et abstractions utiles de l'interface utilisateur.

cschuff
la source
2

Dans le cas Swift 2.0ou plus, le code ci-dessous fonctionnera:

pageControl.pageIndicatorTintColor = UIColor.whiteColor()
pageControl.currentPageIndicatorTintColor = UIColor.redColor()
Sohil R. Memon
la source
1

Il n'est pas possible d'utiliser le SDK iPhone d'un point de vue officiel. Vous pourrez peut-être le faire en utilisant des méthodes privées, mais ce sera un obstacle pour accéder à l'App Store.

La seule autre solution sûre est de créer votre propre contrôle de page, ce qui ne sera pas trop difficile étant donné que le contrôle de page affiche simplement la page actuellement affichée dans une vue de défilement.

Jasarien
la source
Theere n'est pas un lien vers ma solution. Ma solution est là dans le texte juste au-dessus de votre commentaire. Cherchez les méthodes privées (je ne saurai pas ce qu'elles sont) ou écrivez les vôtres (je ne vais pas le faire pour vous).
Jasarien
-1
myView.superview.tintColor = [UIColor colorWithRed:1.0f  
                                      green:1.0f blue:1.0f alpha:1.0f];
Michael Bélanger
la source