Làm cách nào để thay đổi màu của các chấm phân trang của UIPageControl?


178

Tôi đang phát triển một ứng dụng mà tôi muốn thay đổi màu sắc hoặc hình ảnh của các UIPageControlchấm phân trang. Làm thế nào tôi có thể thay đổi nó? Có thể tùy chỉnh UIpageControltrên kịch bản trên?

Câu trả lời:


266

CẬP NHẬT:

Câu trả lời này đã 6 tuổi và rất lỗi thời, nhưng nó vẫn thu hút phiếu bầu và bình luận. Kể từ iOS 6.0, bạn nên sử dụng pageIndicatorTintColorcurrentPageIndicatorTintColorcác thuộc tính trên UIPageControl.

TRẢ LỜI GỐC:

Tôi gặp vấn đề này ngày hôm nay và quyết định viết lớp thay thế đơn giản của riêng tôi.

Đó là một UIView được phân lớp sử dụng Đồ họa lõi để hiển thị các chấm theo màu bạn chỉ định.

Bạn sử dụng các thuộc tính tiếp xúc để tùy chỉnh và kiểm soát nó.

Nếu bạn muốn, bạn có thể đăng ký một đối tượng ủy nhiệm để nhận thông báo khi người dùng chạm vào một trong những dấu chấm trang nhỏ. Nếu không có đại biểu nào được đăng ký thì chế độ xem sẽ không phản ứng với đầu vào cảm ứng.

Nó hoàn toàn mới từ lò nướng, nhưng dường như hoạt động. Hãy cho tôi biết nếu bạn gặp phải bất kỳ vấn đề với nó.

Những cải tiến trong tương lai:

  • Thay đổi kích thước các chấm để phù hợp với giới hạn hiện tại nếu có quá nhiều.
  • Không vẽ lại toàn bộ khung nhìn trong drawRect:

Ví dụ sử dụng:

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

Tập tin tiêu đề:

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

Hồ sơ thực hiện:

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

Vậy làm thế nào để làm việc này? Tôi đang sử dụng phương pháp pagecontrolPageDidChange và tôi không nhận được gì. Tôi không thể nhấp vào bất kỳ nút nào
Adam

HI Heiberg, tôi đã sử dụng điều này để thay đổi trang cuộn của tôi, làm thế nào để bạn làm điều đó từ mã của bạn? [pageControl1 addTarget: tự hành động: @selector (changePage :) forControlEvents: UIControlEventValueChanged];
Desmond

// Hành động thay đổi trang trên UIPageControl - (void) changePage: (UIPageControl *) control {// int page = pageControl.civersePage; int page = pageControl.c hiệnPage; // cập nhật chế độ xem cuộn lên trang thích hợp CGRect frame = scrollview.frame; frame.origin.x = frame.size. thong * trang; khung.origin.y = 0; [scrollview scrollRectToVisible: khung hình động: CÓ]; pageControlUsed = CÓ; }
Desmond

Để chạy mã này với ARC, bạn chỉ cần xóa phương thức dealloc, thay đổi gán thành yếu và thêm __weak trước khi khai báo thuộc tính liên quan. Rất đẹp. Cảm ơn rất nhiều.
cschuff

thay thế đại biểu NSObject <PageControlDelegate> * bằng đại biểu id __unsafe_unretained; trong tiêu đề để giải quyết cảnh báo ARC
Mihir Mehta

150

Trong iOS 6, bạn có thể đặt màu sắc của UIPageControl:

Có 2 thuộc tính mới:

  • pageIndicatorTintColor
  • currentPageIndicatorTintColor

Bạn cũng có thể sử dụng API xuất hiện để thay đổi màu sắc của tất cả các chỉ báo trang.

Nếu bạn đang nhắm mục tiêu iOS 5, hãy đảm bảo nó không bị sập:

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

Còn iOS 5 thì sao? Làm thế nào để bạn chắc chắn rằng điều này không sụp đổ?
jjxtra

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

hoạt động cho iOS6


2
Tôi đã rất bối rối rằng tôi sẽ cần phải phân lớp UIPageControl. Điều này đã lừa Điều này nên ở vị trí số 1.
Forrest

Tại sao một câu trả lời phức tạp như vậy lại được bình chọn hàng đầu khi đây đúng là tất cả những gì bạn cần?
Taylor ALLred

23

Trong trường hợp bất kỳ ai cũng muốn có phiên bản ARC / hiện đại của nó (không cần xác định lại các thuộc tính là ivar, không dealloc và hoạt động với 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

TrangControl.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
Một bổ sung nhỏ để ngăn nó gửi cho đại biểu nếu số trang thực sự không thay đổi sau một cú chạm. NSInteger newPage = sàn (x / (kDotDiameter + kDotSpacer)); if (self.cienPage == newPage) return;
theLastNightTrain

15

Câu trả lời được cung cấp bởi Heiberg hoạt động thực sự tốt, tuy nhiên điều khiển trang không hoạt động chính xác như câu trả lời của apple.

Nếu bạn muốn điều khiển trang hoạt động giống như điều khiển từ apple (luôn luôn tăng trang hiện tại lên một nếu bạn chạm vào nửa thứ hai, nếu không thì giảm một), thay vào đó, hãy thử phương thức chạm này:

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

Thêm mã sau vào DidFinishLauch trong AppDelegate,

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

Hy vọng điều này sẽ giúp.


6

sử dụng điều này để mã hóa

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

hoặc từ bảng phân cảnh, bạn có thể thay đổi từ màu trang hiện tại

nhập mô tả hình ảnh ở đây


Cảm ơn ... tiếp tục chia sẻ :)
Tirth

6

Trong Swift, mã này bên trong UIPageViewCont kiểm soát đang tham chiếu đến chỉ báo trang và đặt thuộc tính của nó

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

UIPageControlkhông giống nhưUIPageViewController
jungledev


4

Thật dễ dàng với Swift 1.2:

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

3
Điều này đặt nó trên toàn cầu. Nếu bạn có nhiều UIPageControls trong ứng dụng của mình và bạn cần các màu khác nhau dựa trên lớp thì hãy sử dụng UIPageControl.appearanceWhenContainedInInstancesOfClasses([MyClassName.self])thay vì UIPageControl.appearance(). Yêu cầu iOS 9.
Jon

4

Bạn có thể khắc phục dễ dàng bằng cách thêm mã sau vào tệp appdelegate.m trong didFinishLaunchingWithOptionsphương thức của mình :

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

3

Điều này được làm việc cho tôi trong iOS 7.

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

2

Không thể sử dụng SDK iPhone từ quan điểm chính thức. Bạn có thể làm điều đó bằng các phương thức riêng tư, nhưng đó sẽ là rào cản để vào cửa hàng ứng dụng.

Giải pháp an toàn duy nhất khác là tạo điều khiển trang riêng của bạn, điều mà shpuldnt quá khó khăn vì điều khiển trang chỉ hiển thị trang nào hiện đang hiển thị trong chế độ xem cuộn.


Đây không phải là một liên kết đến giải pháp của tôi. Giải pháp của tôi là có trong văn bản ngay phía trên bình luận của bạn. Hoặc tìm kiếm các phương thức riêng tư (tôi sẽ không biết chúng là gì) hoặc tự viết (tôi sẽ không làm điều đó cho bạn).
Jasarien

2

@Jasarien Tôi nghĩ rằng bạn có thể phân lớp UIPageControll, dòng được chọn từ apple doc "Các lớp con tùy chỉnh giao diện của điều khiển trang có thể sử dụng phương pháp này để thay đổi kích thước điều khiển trang khi số trang thay đổi" cho kích thước phương thứcForNumberOfPages:


2

Bạn cũng có thể sử dụng Thư viện Three20 có chứa PageControl có thể cách điệu và hàng tá các Điều khiển và trừu tượng UI hữu ích khác.


2

Trong trường hợp Swift 2.0trở lên, mã dưới đây sẽ hoạt động:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.