UIPageControlのアイコンを変える

いま作ってるiOSアプリで、ホーム画面に使われているUIPageControlみたいに、一番左の点だけ独自のアイコンに変更したかったのでやってみた。

ところで、UIPageControlって、何故こんなにもカスタマイズ性が低いのだろうか?
需要や見た目どころの話でなく、背景が白くなった場合に、全く機能を果たせないというのは致命的だ。

UIPageControlの点はUIImageView!?

調べてみたところ、このUIPageControlの白や黒の点は、ただのUIImageViewであることがわかった。

あるところでは、UIPageControlがUIImageViewを管理している配列_indicatorsをhackして〜ということをやっていたが、海外のサイトをあさっていたら、物凄く簡単な方法を発見した。

まずUIPageControlを継承したクラスを作る。
白黒の点がUIImageViewであるということは、必ずUIPageControlにaddSubviewされているはずなので、UIPageControlのsubviewsから、objectAtIndex:で、サブビューを順番に取り出して、isKindOfClass:でUIImageViewであることを確認してから、そのimageプロパティを独自のUIImageに変更する(アイコンのサイズは12×12)。

あと注意すべきは、currentPageを変更すると、UIImageViewもすべて書き直されてしまうらしいので、currentPageプロパティのセッタをオーバライドして、setNeedsDisplayメソッドで、drawRect:を呼び出してやる必要があること。

以下、UIPageControlを継承したクラスの実装。

CustomPageControl.h

#import <Foundation/Foundation.h>

@interface CustomPageControl : UIPageControl
{
}
@end

CustomPageControl.m

#import "CustomPageControl.h"

@implementation CustomPageControl

- (id)initWithFrame:(CGRect)frame{
    if (self = [super initWithFrame:frame])
    {
        self.backgroundColor = [UIColor clearColor];
    }
    return self;
}
- (void)drawRect:(CGRect)rect{
    for (int i = 0; i < self.numberOfPages; i++)
    {
        UIImageView *pageIcon = [self.subviews objectAtIndex:i];

        if ([pageIcon isKindOfClass:[UIImageView class]] && i == 0)
        {
            if (i == self.currentPage)
            {
                pageIcon.image = [UIImage imageNamed:@"PageIcon_Active.png"];
            }
            else
            {
                pageIcon.image = [UIImage imageNamed:@"PageIcon.png"];
            }
        }
    }
}
- (void)setCurrentPage:(NSInteger)curPageIndex{
    [super setCurrentPage:curPageIndex];
    [self setNeedsDisplay];
}
@end