UIPageControl의 페이지 매김 점의 색상을 어떻게 변경합니까?


178

UIPageControl페이지 매김 점 의 색상이나 이미지를 변경하려는 응용 프로그램을 개발 중 입니다. 어떻게 바꾸나요? UIpageControl위 시나리오 에서 사용자 정의 할 수 있습니까?

답변:


266

최신 정보:

이 답변은 6 살이며 매우 구식이지만 여전히 투표와 의견을 끌어 들이고 있습니다. iOS 6.0부터는 pageIndicatorTintColorcurrentPageIndicatorTintColor속성을 사용해야합니다 UIPageControl.

원래 답변 :

나는 오늘이 문제에 부딪 쳤고 내 자신의 간단한 대체 수업을 작성하기로 결정했습니다.

핵심 그래픽을 사용하여 지정한 색상으로 점을 렌더링하는 소문이 나는 UIView입니다.

노출 된 특성을 사용하여 사용자 정의하고 제어하십시오.

원하는 경우 사용자가 작은 페이지 점 중 하나를 누를 때 알림을 받도록 델리게이트 개체를 등록 할 수 있습니다. 델리게이트가 등록되어 있지 않으면 뷰가 터치 입력에 반응하지 않습니다.

오븐에서 완전히 신선하지만 작동하는 것 같습니다. 문제가 발생하면 알려주십시오.

향후 개선 사항 :

  • 현재 경계가 너무 많으면 점의 크기를 조정하십시오.
  • 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

안녕 Heiberg, 나는 이것을 사용하여 scrollview의 내 페이지를 변경했다. 어떻게 코드에서 그것을합니까? [pageControl1 addTarget : self action : @selector (changePage :) forControlEvents : UIControlEventValueChanged];
Desmond

// 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 애니메이션 : YES]; pageControlUsed = 예; }
Desmond

이 코드를 ARC와 함께 실행하려면 dealloc 메소드를 제거하고 assign을 weak로 변경하고 관련 속성 선언 전에 __weak을 추가하면됩니다. 아주 좋아요 고마워
cschuff 2016

NSObject <PageControlDelegate> * delegate를 __unsafe_unretained id 대리자로 교체하십시오. 헤더에 ARC 경고를 해결하기 위해
미 히어 메타에게

150

iOS 6에서는 색조 색상을 설정할 수 있습니다 UIPageControl.

새로운 2 가지 속성이 있습니다 :

  • pageIndicatorTintColor
  • currentPageIndicatorTintColor

모양 API를 사용하여 모든 페이지 표시기의 색조 색상을 변경할 수도 있습니다.

iOS 5를 대상으로하는 경우 충돌하지 않는지 확인하십시오.

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

iOS 5는 어떻습니까? 이것이 충돌하지 않는지 어떻게 확인합니까?
jjxtra

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

iOS6에서 작동


2
UIPageControl을 서브 클래스 화해야한다고 생각했습니다. 이 트릭을했다. 위치 # 1에 있어야합니다.
포레스트

이것이 문자 그대로 필요한 모든 경우에 왜 이렇게 복잡한 답이 가장 많이 투표 된 것입니까?
TaylorAllred

23

누구든지 ARC / 현대 버전을 원할 경우 (ivar로 속성을 재정의 할 필요가없고, 할당 취소하지 않고 인터페이스 빌더와 함께 작동) :

#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 = 바닥 (x / (kDotDiameter + kDotSpacer)); if (self.currentPage == newPage) 반환;
theLastNightTrain

15

Heiberg가 제공하는 답변은 실제로 잘 작동하지만 페이지 컨트롤은 Apple의 페이지 컨트롤과 똑같이 동작하지 않습니다.

페이지 컨트롤이 애플의 페이지 컨트롤처럼 작동하도록하려면 (두 번째 절반을 터치하면 항상 현재 페이지를 1 씩 늘리고, 그렇지 않으면 1 씩 줄입니다) 대신 다음 touchesBegan-method를 사용해보십시오.

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

5

기존 답변에 추가하면 다음과 같이 수행 할 수 있습니다.

여기에 이미지 설명을 입력하십시오


4

Swift 1.2를 사용하면 쉽습니다.

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

3
이것은 세계적으로 설정합니다. 앱에 여러 UIPageControls가 있고 클래스에 따라 다른 색상이 필요한 경우 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는 내 솔루션에 대한 링크가 아닙니다. 내 해결책은 귀하의 의견 바로 위에 텍스트로 있습니다. 개인적인 방법을 찾거나 (이것이 무엇인지 모르겠습니다) 직접 작성하십시오 (나는 당신을 위해 그렇게하지 않을 것입니다).
Jasarien

2

@Jasarien UIdocControll을 서브 클래 싱 할 수 있다고 생각합니다. 애플 페이지에서만 선택한 "페이지 컨트롤의 모양을 사용자 정의하는 서브 클래스는이 메서드를 사용하여 페이지 개수가 변경 될 때 페이지 컨트롤의 크기를 조정할 수 있습니다."


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.