Як я можу змінити колір точок сторінки на UIPageControl?


178

Я розробляю програму, в якій хочу змінити колір або зображення UIPageControlточок сторінки. Як я можу це змінити? Чи можливо налаштувати UIpageControlза вищевказаним сценарієм?

Відповіді:


266

ОНОВЛЕННЯ:

Ця відповідь 6 років і дуже застаріла, але вона все ще привертає голоси та коментарі. Починаючи з iOS 6.0, ви повинні використовувати pageIndicatorTintColorі currentPageIndicatorTintColorввімкнено властивості UIPageControl.

ОРИГІНАЛЬНИЙ ВІДПОВІДЬ:

Я сьогодні зіткнувся з цією проблемою і вирішив написати власний простий клас заміни.

Це підкласовий UIView, який використовує Core Graphics для відображення точок у вказаних кольорах.

Ви використовуєте відкриті властивості для налаштування та керування ними.

Якщо ви хочете, ви можете зареєструвати об’єкт-делегат, щоб отримувати сповіщення, коли користувач натискає одну з маленьких точок сторінки. Якщо жодного делегата не зареєстровано, подання не буде реагувати на сенсорний ввід.

Він повністю свіжий з духовки, але, здається, працює. Повідомте мене, якщо у вас виникнуть якісь проблеми з цим.

Майбутні вдосконалення:

  • Змініть розмір крапок, щоб відповідати поточним межам, якщо їх занадто багато.
  • Не перемальовуйте весь вигляд у drawRect:

Приклад використання:

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

Файл заголовка:

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

Файл реалізації:

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

То як це працює? Я використовую метод pagecontrolPageDidChange, і я нічого не отримую. Я не можу натиснути жодну з кнопок
Adam

Привіт Хайберг, я використовував це, щоб змінити свою сторінку прокрутки, як це зробити з коду? [pageControl1 addTarget: самодія: @selector (changePage :) forControlEvents: UIControlEventValueChanged];
Десмонд

// Дія щодо зміни сторінки на UIPageControl - (недійсна) changePage: (UIPageControl *) контроль {// int page = pageControl.currentPage; int page = pageControl.currentPage; // оновити подання прокрутки до відповідної сторінки CGRect frame = scrollview.frame; frame.origin.x = frame.size.width * сторінка; frame.origin.y = 0; [scrollview scrollRectToVisible: кадр анімований: ТАК]; pageControlUsed = ТАК; }
Десмонд

Для запуску цього коду з ARC вам просто потрібно буде видалити метод dealloc, змінити призначення на слабкий і додати __weak перед відповідним декларацією властивості. Дуже хороша. Дуже дякую.
cschuff

замініть делегат NSObject <PageControlDelegate> * на делегат __unsafe_unreished id; в шапці, щоб вирішити попередження ARC
Mihir Mehta

150

В iOS 6 можна встановити колір відтінку UIPageControl:

Є 2 нові властивості:

  • pageIndicatorTintColor
  • currentPageIndicatorTintColor

Ви також можете використовувати API зовнішнього вигляду, щоб змінити колір відтінку всіх індикаторів сторінки.

Якщо ви орієнтовані на iOS 5, переконайтеся, що він не виходить з ладу:

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

Що з iOS 5? Як ви переконаєтесь, що це не виходить з ладу?
jjxtra

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

працює для iOS6


2
Мене зіткнуло, що мені буде потрібно підклас UIPageControl. Це зробило трюк. Це має бути в позиції №1.
Форрест

Чому за таку складну відповідь проголосував верх, коли це буквально все, що вам потрібно?
ТейлорАлред

23

У випадку, якщо хтось хоче ARC / сучасної його версії (не потрібно переосмислювати властивості як ivar, no dealloc та працює з 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
Невелике доповнення, щоб зупинити його надсилання делегату, якщо номер сторінки насправді не змінився після дотику. NSInteger newPage = пол (x / (kDotDiameter + kDotSpacer)); якщо (self.currentPage == newPage) повернення;
theLastNightTrain

15

Відповідь, надана Хайбергом, працює дуже добре, проте контроль сторінки не веде себе так, як яблуко.

Якщо ви хочете, щоб керування сторінками поводилось так, як це відбувається з яблука (завжди збільшуйте поточну сторінку на одну, якщо торкніться другої половини, інакше зменшіться на одиницю), спробуйте скористатися цим методом "Біган":

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

Додайте наступний код до DidFinishLauch в AppDelegate,

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

Сподіваюсь, це допоможе.


6

використовувати це для кодування

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

або з раскадровки ви можете змінити поточний відтінок сторінки

введіть тут опис зображення


Дякую ... продовжуйте ділитися :)
Tirth

6

У Swift цей код всередині UIPageViewController отримує посилання на індикатор сторінки та встановлює його властивості

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

UIPageControlне те саме, щоUIPageViewController
jungledev

5

Додавши до існуючих відповідей, це можна зробити так,

введіть тут опис зображення


4

З Swift 1.2 це легко:

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

3
Це встановлює це глобально. Якщо у вашому додатку є кілька UIPageControls, і вам потрібні різні кольори на основі класу, тоді використовуйте UIPageControl.appearanceWhenContainedInInstancesOfClasses([MyClassName.self])замість них UIPageControl.appearance(). Потрібно IOS 9.
Джон

4

Ви можете виправити це з легкістю, додавши наступний код у файл appdelegate.m у своєму didFinishLaunchingWithOptionsметоді:

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

3

Для мене це працює в iOS 7.

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

2

Використовувати iPhone SDK з офіційної точки зору неможливо. Ви можете зробити це за допомогою приватних методів, але це буде перешкодою для потрапляння в магазин додатків.

Єдине інше безпечне рішення - створити власний контроль над сторінками, який shpuldnt буде занадто складним, враховуючи, що керування сторінками просто відображає, яку сторінку в даний час відображається у вікні прокрутки.


Theere не є посиланням на моє рішення. Моє рішення є в тексті трохи вище вашого коментаря. Або шукайте приватні методи (я не знаю, що це таке) або пишіть свої (я не збираюся цього робити для вас).
Ясарієн

2

@Jasarien Я думаю, що ви можете підкласити UIPageControll, рядок, вибраний лише з яблучного документу "Підкласи, які налаштовують зовнішній вигляд керування сторінками, можуть використовувати цей метод для зміни розміру керування сторінками при зміні кількості сторінок" для розміру методуForNumberOfPages:


2

Ви також можете використати Бібліотеку Three20, яка містить стилізований PageControl та десятки інших корисних елементів управління та абстракції.


2

У випадку з Swift 2.0і вище, наступний код буде працювати:

pageControl.pageIndicatorTintColor = UIColor.whiteColor()
pageControl.currentPageIndicatorTintColor = UIColor.redColor()

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.