Bagaimana saya bisa mengubah warna titik halaman dari UIPageControl?

178

Saya sedang mengembangkan aplikasi di mana saya ingin mengubah warna atau gambar UIPageControltitik pagination. Bagaimana saya bisa mengubahnya? Apakah mungkin untuk menyesuaikan UIpageControlskenario di atas?

Tirth
sumber

Jawaban:

266

MEMPERBARUI:

Jawaban ini berumur 6 tahun dan sangat ketinggalan zaman, tetapi masih menarik suara dan komentar. Sejak iOS 6.0 Anda harus menggunakan pageIndicatorTintColordan currentPageIndicatorTintColorproperti aktif UIPageControl.

JAWABAN ASLI:

Saya mengalami masalah ini hari ini dan memutuskan untuk menulis kelas penggantian sederhana saya sendiri.

Ini adalah UIView subklas yang menggunakan Core Graphics untuk membuat titik-titik dalam warna yang Anda tentukan.

Anda menggunakan properti yang terbuka untuk menyesuaikan dan mengendalikannya.

Jika mau, Anda dapat mendaftarkan objek delegasi untuk mendapatkan notifikasi ketika pengguna mengetuk salah satu titik halaman kecil. Jika tidak ada delegasi terdaftar maka tampilan tidak akan bereaksi terhadap input sentuhan.

Ini benar-benar segar dari oven, tetapi tampaknya berhasil. Beri tahu saya jika Anda mengalami masalah dengannya.

Perbaikan di masa depan:

  • Ubah ukuran titik agar sesuai dengan batas saat ini jika ada terlalu banyak.
  • Jangan menggambar ulang seluruh tampilan di drawRect:

Contoh penggunaan:

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

File tajuk:

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

File implementasi:

//
//  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
Heiberg
sumber
Jadi bagaimana cara kerjanya? Saya menggunakan metode pagecontrolPageDidChange dan saya tidak mendapatkan apa-apa. Saya tidak dapat mengklik tombol mana pun
Adam
HI Heiberg, saya menggunakan ini untuk mengubah halaman scrollview saya, bagaimana Anda melakukannya dari kode Anda? [pageControl1 addTarget: self action: @selector (changePage :) forControlEvents: UIControlEventValueChanged];
Desmond
// Aksi untuk perubahan halaman pada UIPageControl - (void) changePage: (UIPageControl *) control {// int page = pageControl.currentPage; int page = pageControl.currentPage; // perbarui tampilan gulir ke halaman yang sesuai CGRect frame = scrollview.frame; frame.origin.x = frame.size.width * halaman; frame.origin.y = 0; [scrollview scrollRectToVisible: frame animated: YES]; pageControlUsed = YA; }
Desmond
Untuk menjalankan kode ini dengan ARC Anda hanya perlu menghapus metode dealloc, ubah penetapan menjadi lemah dan tambahkan __weak sebelum deklarasi properti yang bersangkutan. Sangat bagus. Terima kasih banyak.
cschuff
ganti NSObject <PageControlDelegate> * delegate dengan __unsafe_unretained id delegate; di header untuk menyelesaikan peringatan ARC
Mihir Mehta
150

Di iOS 6 Anda dapat mengatur warna rona UIPageControl:

Ada 2 properti baru:

  • pageIndicatorTintColor
  • currentPageIndicatorTintColor

Anda juga dapat menggunakan API penampilan untuk mengubah warna warna semua indikator halaman.

Jika Anda menargetkan iOS 5 pastikan tidak macet:

if ([pageControl respondsToSelector:@selector(setPageIndicatorTintColor:)]) {
    pageControl.pageIndicatorTintColor = [UIColor whiteColor];
}
Felix
sumber
Bagaimana dengan iOS 5? Bagaimana Anda memastikan ini tidak crash?
jjxtra
41
pageControl.pageIndicatorTintColor = [UIColor redColor];
pageControl.currentPageIndicatorTintColor = [UIColor redColor];

bekerja untuk iOS6

Add080bbA
sumber
2
Saya kecewa bahwa saya akan perlu untuk subkelas UIPageControl. Ini berhasil. Ini harus di posisi # 1.
Forrest
Mengapa jawaban yang rumit ini dipilih sebagai yang teratas saat ini benar-benar yang Anda butuhkan?
TaylorAllred
23

Jika ada yang menginginkan versi ARC / modern (tidak perlu mendefinisikan ulang properti sebagai ivar, tidak ada dealloc, dan bekerja dengan 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
Ben G
sumber
1
Tambahan kecil untuk menghentikan pengiriman ke delegasi jika nomor halaman tidak benar-benar berubah setelah disentuh. NSInteger newPage = lantai (x / (kDotDiameter + kDotSpacer)); jika (self.currentPage == newPage) kembali;
theLastNightTrain
15

Jawaban yang diberikan oleh Heiberg bekerja sangat baik, namun kontrol halaman tidak berperilaku persis seperti yang dilakukan oleh apel.

Jika Anda ingin kontrol halaman berperilaku seperti yang dilakukan oleh apple (selalu naikkan halaman saat ini satu per satu jika Anda menyentuh bagian kedua, sebaliknya turun satu per satu), coba ini sentuhMulai-metode sebagai gantinya:

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

Tambahkan kode berikut ke DidFinishLauch di AppDelegate,

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

Semoga ini bisa membantu.

posha
sumber
6

gunakan ini untuk coding

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

atau dari storyboard Anda dapat mengubah dari warna halaman saat ini

masukkan deskripsi gambar di sini

Pooja Patel
sumber
Terima kasih ... terus berbagi :)
Tirth
6

Di Swift, kode ini di dalam UIPageViewController mendapatkan referensi ke indikator halaman dan mengatur propertinya

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()
}
arbel03
sumber
UIPageControltidak sama denganUIPageViewController
jungledev
5

Menambahkan ke jawaban yang ada, itu bisa dilakukan seperti,

masukkan deskripsi gambar di sini

aToz
sumber
4

Mudah dengan Swift 1.2:

UIPageControl.appearance().pageIndicatorTintColor           = UIColor.lightGrayColor()
UIPageControl.appearance().currentPageIndicatorTintColor    = UIColor.redColor()
Oleg Popov
sumber
3
Ini membuatnya secara global. Jika Anda memiliki beberapa UIPageControls di aplikasi Anda dan Anda membutuhkan warna berbeda berdasarkan kelas, gunakan UIPageControl.appearanceWhenContainedInInstancesOfClasses([MyClassName.self])alih-alih UIPageControl.appearance(). Membutuhkan iOS 9.
Jon
4

Anda dapat memperbaikinya dengan mudah dengan menambahkan kode berikut ke file appdelegate.m Anda di didFinishLaunchingWithOptionsmetode Anda :

UIPageControl *pageControl = [UIPageControl appearance];
pageControl.pageIndicatorTintColor = [UIColor darkGrayColor];
pageControl.currentPageIndicatorTintColor = [UIColor orangeColor];
pageControl.backgroundColor = [UIColor whiteColor]
Nabil El Atlas
sumber
3

Ini berfungsi untuk saya di iOS 7.

pageControl.pageIndicatorTintColor = [UIColor purpleColor];
pageControl.currentPageIndicatorTintColor = [UIColor magentaColor];
Sid
sumber
2

Tidak mungkin menggunakan iPhone SDK dari sudut pandang resmi. Anda mungkin dapat melakukannya dengan menggunakan metode pribadi, tetapi itu akan menjadi penghalang untuk masuk ke app store.

Satu-satunya solusi aman lainnya adalah membuat kontrol halaman Anda sendiri yang seharusnya terlalu sulit mengingat kontrol halaman hanya menampilkan halaman apa yang saat ini ditampilkan dalam tampilan gulir.

Jasarien
sumber
Tidak ada tautan ke solusi saya. Solusi saya ada dalam teks tepat di atas komentar Anda. Baik mencari metode pribadi (saya tidak akan tahu apa ini) atau menulis sendiri (saya tidak akan melakukannya untuk Anda).
Jasarien
2

@Jasarien Saya pikir Anda dapat mensubclass UIPageControll, baris yang dipilih hanya dari apple doc "Subclass yang menyesuaikan tampilan kontrol halaman dapat menggunakan metode ini untuk mengubah ukuran kontrol halaman ketika jumlah halaman berubah" untuk metode sizeForNumberOfPages:

dsaw
sumber
2

Anda juga bisa menggunakan Pustaka Three20 yang berisi PageControl yang bergaya dan lusinan Kontrol dan Abstraksi UI lainnya yang bermanfaat.

cuffuff
sumber
2

Dalam cased Swift 2.0dan up, kode di bawah ini akan berfungsi:

pageControl.pageIndicatorTintColor = UIColor.whiteColor()
pageControl.currentPageIndicatorTintColor = UIColor.redColor()
Sohil R. Memon
sumber
-1
myView.superview.tintColor = [UIColor colorWithRed:1.0f  
                                      green:1.0f blue:1.0f alpha:1.0f];
Michael Belanger
sumber