UIPageControlのページ区切りドットの色を変更するにはどうすればよいですか?


178

UIPageControlページネーションドットの色またはイメージを変更するアプリケーションを開発しています。どうすれば変更できますか?UIpageControl上記のシナリオでカスタマイズすることは可能ですか?

回答:


266

更新:

この回答は6年前のもので、非常に古くなっていますが、それでも投票とコメントを集めています。iOS 6.0以降では、pageIndicatorTintColorおよびのcurrentPageIndicatorTintColorプロパティを使用する必要がありますUIPageControl

元の回答:

今日、この問題に遭遇し、自分で簡単な置換クラスを作成することにしました。

これは、Core Graphicsを使用して、指定した色でドットをレンダリングするサブレーザーUIViewです。

公開されたプロパティを使用して、それをカスタマイズおよび制御します。

必要に応じて、デリゲートオブジェクトを登録して、ユーザーが小さなページドットの1つをタップしたときに通知を受け取ることができます。デリゲートが登録されていない場合、ビューはタッチ入力に反応しません。

それはオーブンから完全に新鮮ですが、動作するようです。問題が発生した場合はお知らせください。

今後の改善:

  • ドットが多すぎる場合は、現在の境界に合わせてドットのサイズを変更します。
  • 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

こんにちはハイバーグ、私はこれを使ってscrollviewのページを変更しましたが、コードからどのように変更しますか?[pageControl1 addTarget:self action:@selector(changePage :) forControlEvents:UIControlEventValueChanged];
デズモンド

// UIPageControlでのページ変更のアクション-(void)changePage:(UIPageControl *)control {// int page = pageControl.currentPage; int page = pageControl.currentPage; //スクロールビューを適切なページに更新しますCGRect frame = scrollview.frame; frame.origin.x = frame.size.width *ページ; frame.origin.y = 0; [scrollview scrollRectToVisible:frame animated:YES]; pageControlUsed = YES; }
デズモンド

ARCでこのコードを実行するには、deallocメソッドを削除し、assignをweakに変更して、関連するプロパティ宣言の前に__weakを追加するだけです。非常に素晴らしい。どうもありがとう。
cschuff 2011

NSObject <PageControlDelegate> * delegateを__unsafe_unretained idデリゲートに置き換えます。ヘッダーでARC警告を解決する
Mihir Mehta 2013

150

iOS 6では、次の色合いを設定できますUIPageControl

2つの新しいプロパティがあります。

  • pageIndicatorTintColor
  • currentPageIndicatorTintColor

また、Appearance APIを使用して、すべてのページインジケーターのティントカラーを変更することもできます。

iOS 5をターゲットにしている場合は、クラッシュしないことを確認してください。

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

iOS 5はどうですか?これがクラッシュしないことをどのように確認しますか?
jjxtra 2013

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

iOS6で動作します


2
UIPageControlをサブクラス化する必要があるのではないかと困惑しました。これでうまくいきました。これは#1の位置にあるはずです。
フォレスト2014

これが文字通り必要なのに、なぜこのような複雑な回答がトップ投票に回答したのですか?
TaylorAllred、2015年

23

ARC /最新バージョンが必要な場合(プロパティをivarとして再定義する必要はなく、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 = floor(x /(kDotDiameter + kDotSpacer)); if(self.currentPage == newPage)return;
theLastNightTrain

15

Heibergから提供された回答は非常にうまく機能しますが、ページコントロールはappleによるものとまったく同じようには動作しません。

アップルのページコントロールと同じようにページコントロールを動作させたい場合(現在のページを後半にタッチした場合は常に1ずつ増やし、それ以外の場合は1ずつ減らします)、代わりにこの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]; 
    }   
}

8

次のコードをAppDelegateのDidFinishLauchに追加します。

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
異なります

5

既存の回答に追加すると、次のようにできます

ここに画像の説明を入力してください


4

Swift 1.2なら簡単です。

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

3
これにより、グローバルに設定されます。アプリに複数のUIPageControlがあり、クラスに基づいて異なる色が必要な場合は、のUIPageControl.appearanceWhenContainedInInstancesOfClasses([MyClassName.self])代わりにを使用してくださいUIPageControl.appearance()。iOS 9が必要
Jon

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を使用することはできません。あなたはプライベートな方法を使用してそれを行うことができるかもしれませんが、それはアプリストアに入るのの障壁になります。

他の唯一の安全なソリューションは、独自のページコントロールを作成することです。これは、ページコントロールが現在スクロールビューに表示されているページを表示するだけなので、難しくありません。


Theereは私のソリューションへのリンクではありません。私の解決策は、コメントのすぐ上のテキストにあります。プライベートメソッドを探す(これらが何であるかわからない)か、独自のメソッドを書く(私はあなたのためにそれを行うつもりはありません)。
ジャサリエン

2

@Jasarien UIPageControllをサブクラス化できると思います。Appledocからのみラインを選択します。メソッドsizeForNumberOfPagesの「ページコントロールの外観をカスタマイズするサブクラスは、このメソッドを使用して、ページ数が変更されたときにページコントロールのサイズを変更できます」:


2

また、スタイル可能なPageControlと他の数十の便利なUIコントロールと抽象化を含むThree20ライブラリを使用することもできます。


2

以上のSwift 2.0場合、以下のコードが機能します。

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.