Wie kann ich die Farbe der Paginierungspunkte von UIPageControl ändern?


178

Ich entwickle eine Anwendung, in der ich entweder die Farbe oder das Bild von UIPageControlPaginierungspunkten ändern möchte . Wie kann ich das ändern? Ist es möglich, das UIpageControlobige Szenario anzupassen ?

Antworten:


266

AKTUALISIEREN:

Diese Antwort ist 6 Jahre alt und sehr veraltet, zieht aber immer noch Stimmen und Kommentare an. Seit iOS 6.0 sollten Sie die Eigenschaften pageIndicatorTintColorund currentPageIndicatorTintColorverwenden UIPageControl.

URSPRÜNGLICHE ANTWORT:

Ich bin heute auf dieses Problem gestoßen und habe beschlossen, meine eigene einfache Ersatzklasse zu schreiben.

Es ist eine untergeordnete UIView, die Core Graphics verwendet, um die Punkte in den von Ihnen angegebenen Farben zu rendern.

Sie verwenden die exponierten Eigenschaften, um sie anzupassen und zu steuern.

Wenn Sie möchten, können Sie ein Delegatenobjekt registrieren, um Benachrichtigungen zu erhalten, wenn der Benutzer auf einen der kleinen Seitenpunkte tippt. Wenn kein Delegat registriert ist, reagiert die Ansicht nicht auf Berührungseingaben.

Es ist völlig frisch aus dem Ofen, scheint aber zu funktionieren. Lassen Sie mich wissen, wenn Sie Probleme damit haben.

Zukünftige Verbesserungen:

  • Ändern Sie die Größe der Punkte, um sie an die aktuellen Grenzen anzupassen, wenn zu viele vorhanden sind.
  • Zeichnen Sie nicht die gesamte Ansicht in drawRect neu:

Anwendungsbeispiel:

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

Header-Datei:

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

Implementierungsdatei:

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

Wie funktioniert das? Ich verwende die pagecontrolPageDidChange-Methode und erhalte nichts. Ich kann keine der Schaltflächen anklicken
Adam

Hallo Heiberg, ich habe dies verwendet, um meine Seite der Bildlaufansicht zu ändern. Wie machst du das mit deinem Code? [pageControl1 addTarget: self action: @selector (changePage :) forControlEvents: UIControlEventValueChanged];
Desmond

// Aktion zum Seitenwechsel in UIPageControl - (void) changePage: (UIPageControl *) control {// int page = pageControl.currentPage; int page = pageControl.currentPage; // aktualisiere die Bildlaufansicht auf die entsprechende Seite CGRect frame = scrollview.frame; frame.origin.x = frame.size.width * page; frame.origin.y = 0; [scrollview scrollRectToVisible: Rahmen animiert: JA]; pageControlUsed = YES; }
Desmond

Um diesen Code mit ARC auszuführen, müssen Sie lediglich die Dealloc-Methode entfernen, die Zuweisung in schwach ändern und vor der betreffenden Eigenschaftsdeklaration eine __schwache Methode hinzufügen. Sehr schön. Vielen Dank.
Cschuff

Ersetzen Sie NSObject <PageControlDelegate> * delegate durch __unsafe_unretained id delegate. im Header zur Lösung der ARC-Warnung
Mihir Mehta

150

In iOS 6 können Sie die Farbtonfarbe einstellen für UIPageControl:

Es gibt 2 neue Eigenschaften:

  • pageIndicatorTintColor
  • currentPageIndicatorTintColor

Sie können auch die Darstellungs-API verwenden, um die Farbtonfarbe aller Seitenindikatoren zu ändern.

Wenn Sie auf iOS 5 abzielen, stellen Sie sicher, dass es nicht abstürzt:

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

Was ist mit iOS 5? Wie stellen Sie sicher, dass dies nicht abstürzt?
jjxtra

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

funktioniert für iOS6


2
Ich war verblüfft, dass ich UIPageControl unterordnen musste. Das hat den Trick gemacht. Dies sollte sich auf Position 1 befinden.
Forrest

Warum ist eine so komplexe Antwort die am besten gewählte, wenn dies buchstäblich alles ist, was Sie brauchen?
TaylorAllred

23

Falls jemand eine ARC / moderne Version davon möchte (keine Notwendigkeit, Eigenschaften als ivar neu zu definieren, kein Dealloc und arbeitet mit 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
Eine kleine Ergänzung, um das Senden an den Delegierten zu stoppen, wenn sich die Seitenzahl nach einer Berührung nicht geändert hat. NSInteger newPage = floor (x / (kDotDiameter + kDotSpacer)); if (self.currentPage == newPage) return;
theLastNightTrain

15

Die Antwort von Heiberg funktioniert sehr gut, aber das Seitensteuerelement verhält sich nicht genau wie das von Apple.

Wenn Sie möchten, dass sich das Seitensteuerelement wie das von Apple verhält (erhöhen Sie die aktuelle Seite immer um eins, wenn Sie die zweite Hälfte berühren, andernfalls um eins verringern), versuchen Sie stattdessen diese touchBegan-Methode:

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

Fügen Sie DidFinishLauch in AppDelegate den folgenden Code hinzu:

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

Hoffe das wird helfen.


6

Verwenden Sie dies zum Codieren

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

oder über das Storyboard können Sie die aktuelle Seitentönung ändern

Geben Sie hier die Bildbeschreibung ein


Danke ... weiter teilen :)
Tirth

6

In Swift erhält dieser Code im UIPageViewController einen Verweis auf die Seitenanzeige und legt deren Eigenschaften fest

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

UIPageControlist nicht dasselbe wieUIPageViewController
jungledev

5

Das Hinzufügen zu vorhandenen Antworten kann wie folgt erfolgen:

Geben Sie hier die Bildbeschreibung ein


4

Mit Swift 1.2 ist das ganz einfach:

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

3
Dies setzt es global. Wenn Ihre App mehrere UIPageControls enthält und Sie je nach Klasse unterschiedliche Farben benötigen, verwenden Sie UIPageControl.appearanceWhenContainedInInstancesOfClasses([MyClassName.self])stattdessen anstelle von UIPageControl.appearance(). Benötigt iOS 9.
Jon

4

Sie können das Problem problemlos beheben, indem Sie Ihrer appdelegate.m- Datei in Ihrer didFinishLaunchingWithOptionsMethode den folgenden Code hinzufügen :

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

3

Dies funktioniert für mich in iOS 7.

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

2

Es ist aus offizieller Sicht nicht möglich, das iPhone SDK zu verwenden. Möglicherweise können Sie dies mit privaten Methoden tun, dies ist jedoch ein Hindernis für den Zugriff auf den App Store.

Die einzige andere sichere Lösung besteht darin, ein eigenes Seitensteuerelement zu erstellen, das nicht allzu schwierig sein sollte, da das Seitensteuerelement einfach anzeigt, welche Seite derzeit in einer Bildlaufansicht angezeigt wird.


Theere ist kein Link zu meiner Lösung. Meine Lösung befindet sich im Text direkt über Ihrem Kommentar. Suchen Sie entweder nach den privaten Methoden (ich weiß nicht, was diese sind) oder schreiben Sie Ihre eigenen (ich werde das nicht für Sie tun).
Jasarien

2

@Jasarien Ich denke, Sie können UIPageControll unterordnen, Zeile nur aus Apple Doc ausgewählt. "Unterklassen, die das Erscheinungsbild des Seitensteuerelements anpassen, können diese Methode verwenden, um die Größe des Seitensteuerelements zu ändern, wenn sich die Seitenzahl ändert" für die Methode sizeForNumberOfPages:


2

Sie können auch die Three20-Bibliothek verwenden, die ein stilisierbares PageControl und Dutzende anderer hilfreicher Steuerelemente und Abstraktionen für die Benutzeroberfläche enthält.


2

Ab Swift 2.0und zu funktioniert der folgende Code:

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];
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.