Как изменить цвет точек разбиения на страницы UIPageControl?

Я разрабатываю приложение, в котором я хочу изменить цвет или изображение UIPageControl точек разбивки на страницы. Как я могу его изменить? Можно ли настроить UIPageControl по сценарию выше?

Ответ 1

UPDATE:

Этот ответ 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 <[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

Файл реализации:

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

Ответ 2

В iOS 6 вы можете установить цвет оттенка UIPageControl:

Есть 2 новых свойства:

  • pageIndicatorTintColor
  • currentPageIndicatorTintColor

Вы также можете использовать API внешнего вида для изменения цвета оттенков всех индикаторов страниц.

Если вы настроите iOS 5, убедитесь, что он не сбой:

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

Ответ 3

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

работает для iOS6

Ответ 4

Если кто-то хочет 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

Ответ 5

Ответ, представленный Heiberg, работает очень хорошо, однако элемент управления страницей не ведет себя точно так же, как и яблоко.

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

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

Ответ 6

Добавьте следующий код в DidFinishLauch в AppDelegate,

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

Надеюсь, это поможет.

Ответ 7

Добавляя к существующим ответам, это можно сделать, например,

enter image description here

Ответ 8

Легко с Swift 1.2:

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

Ответ 9

Это работает для меня в iOS 7.

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

Ответ 10

вы можете легко устранить это, добавив в файл appdelegate.m соответствующий код в файле yourFinishLaunchingWithOptions:

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

Ответ 11

используйте это для кодирования

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

или из раскадровки вы можете изменить текущий оттенок страницы

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

Ответ 12

Это невозможно с помощью iPhone SDK с официальной точки зрения. Возможно, вы сможете сделать это с помощью частных методов, но это станет препятствием для входа в магазин приложений.

Единственное другое безопасное решение - создать собственный элемент управления страницы, который shpuldnt будет слишком сложным, учитывая, что элемент управления страницей просто отображает страницу, отображаемую в настоящее время в виде прокрутки.

Ответ 13

@Jasarien Я думаю, что вы можете подклассифицировать UIPageControll, только выбранную из apple doc. "Подклассы, которые настраивают внешний вид элемента управления страницы, могут использовать этот метод для изменения размера элемента управления страницы при изменении количества страниц" для метода sizeForNumberOfPages:

Ответ 14

Вы также можете использовать библиотеку Three20, которая содержит настраиваемый параметр PageControl и десятки других полезных элементов управления и абстракций пользовательского интерфейса.

Ответ 15

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

Ответ 16

В обложенном Swift 2.0 и выше, код ниже будет работать:

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

Ответ 17

Вот решение Swift 3.0... вы знаете, если вы согласны с принятым заявленным риском: "Модификация подсмотров существующего элемента управления является хрупкой".

Вам нужно будет вызвать updateDots() в вашем viewDidAppear() и обработчике valueChanged для управления страницей.

 import UIKit

 class CustomImagePageControl: UIPageControl {

   let activeImage:UIImage = UIImage(named: "SelectedPage")!
   let inactiveImage:UIImage = UIImage(named: "UnselectedPage")!

   override func awakeFromNib() {
         super.awakeFromNib()

         self.pageIndicatorTintColor = UIColor.clear
         self.currentPageIndicatorTintColor = UIColor.clear
         self.clipsToBounds = false
    }

    func updateDots() {
         var i = 0
         for view in self.subviews {
             if let imageView = self.imageForSubview(view) {
                 if i == self.currentPage {
                     imageView.image = self.activeImage
                 } else {
                     imageView.image = self.inactiveImage
                 }
                 i = i + 1
             } else {
                 var dotImage = self.inactiveImage
                 if i == self.currentPage {
                     dotImage = self.activeImage
                 }
                 view.clipsToBounds = false
                 view.addSubview(UIImageView(image:dotImage))
                 i = i + 1
             }
         }
     }

     fileprivate func imageForSubview(_ view:UIView) -> UIImageView? {
         var dot:UIImageView?

         if let dotImageView = view as? UIImageView {
             dot = dotImageView
         } else {
             for foundView in view.subviews {
                 if let imageView = foundView as? UIImageView {
                     dot = imageView
                     break
                 }
             }
         }

         return dot
     }
 }

Ответ 18

myView.superview.tintColor = [UIColor colorWithRed:1.0f  
                                      green:1.0f blue:1.0f alpha:1.0f];