我正在开发一个应用程序,我想在其中更改UIPageControl
分页点的颜色或图像。我该怎么改变它?是否可以在上述方案中自定义UIpageControl
?
答案 0 :(得分:260)
<强>更新强>
这个答案是6岁,非常过时,但它仍然吸引了选票和评论。从iOS 6.0开始,您应该使用pageIndicatorTintColor
上的currentPageIndicatorTintColor
和UIPageControl
属性。
原始答案:
我今天遇到了这个问题并决定编写我自己的简单替换类。
这是一个经过细分的UIView,它使用Core Graphics渲染您指定颜色的点。
您可以使用公开的属性来自定义和控制它。
如果您愿意,可以注册一个委托对象,以便在用户点击其中一个小页面点时收到通知。如果没有注册委托,则视图不会对触摸输入作出反应。
它从烤箱中完全新鲜,但似乎有效。如果您遇到任何问题,请告诉我。
未来的改进:
使用示例:
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
答案 1 :(得分:149)
在iOS 6中,您可以设置UIPageControl
的色调颜色:
有2个新属性:
pageIndicatorTintColor
currentPageIndicatorTintColor
您还可以使用外观API来更改所有页面指示符的色调。
如果您的目标是iOS 5,请确保它不会崩溃:
if ([pageControl respondsToSelector:@selector(setPageIndicatorTintColor:)]) {
pageControl.pageIndicatorTintColor = [UIColor whiteColor];
}
答案 2 :(得分:40)
pageControl.pageIndicatorTintColor = [UIColor redColor];
pageControl.currentPageIndicatorTintColor = [UIColor redColor];
适用于iOS6
答案 3 :(得分: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
答案 4 :(得分:15)
Heiberg提供的答案效果非常好,但是页面控件的行为与apple不同。
如果您希望页面控件的行为类似于来自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];
}
}
答案 5 :(得分:8)
将以下代码添加到AppDelegate中的DidFinishLauch,
UIPageControl *pageControl = [UIPageControl appearance];
pageControl.pageIndicatorTintColor = [UIColor lightGrayColor];
pageControl.currentPageIndicatorTintColor = [UIColor blackColor];
pageControl.backgroundColor = [UIColor whiteColor];
希望这会有所帮助。
答案 6 :(得分:6)
用它来编码
if ([pageControl respondsToSelector:@selector(setPageIndicatorTintColor:)]) {
pageControl.pageIndicatorTintColor = [UIColor whiteColor];
}
或从故事板中,您可以从当前页面色调更改
答案 7 :(得分:5)
在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()
}
答案 8 :(得分:5)
添加到现有答案,可以像
那样完成
答案 9 :(得分:4)
使用Swift 1.2很容易:
UIPageControl.appearance().pageIndicatorTintColor = UIColor.lightGrayColor()
UIPageControl.appearance().currentPageIndicatorTintColor = UIColor.redColor()
答案 10 :(得分:4)
您可以通过在didFinishLaunchingWithOptions
方法中将以下代码添加到 appdelegate.m 文件中轻松修复它:
UIPageControl *pageControl = [UIPageControl appearance];
pageControl.pageIndicatorTintColor = [UIColor darkGrayColor];
pageControl.currentPageIndicatorTintColor = [UIColor orangeColor];
pageControl.backgroundColor = [UIColor whiteColor]
答案 11 :(得分:3)
这在iOS 7中适用于我。
pageControl.pageIndicatorTintColor = [UIColor purpleColor];
pageControl.currentPageIndicatorTintColor = [UIColor magentaColor];
答案 12 :(得分:2)
从官方角度来看,无法使用iPhone SDK。您可以使用私有方法来执行此操作,但这将成为进入应用商店的障碍。
唯一的其他安全解决方案是创建自己的页面控件,因为页面控件只显示当前在滚动视图中显示的页面,所以页面控件太难了。
答案 13 :(得分:2)
您还可以使用包含可设置样式的PageControl的Three20库以及许多其他有用的UI控件和抽象。
答案 14 :(得分:2)
@Jasarien我认为你可以继承子类UIPageControll,仅从apple doc挑选一行“自定义页面控件外观的子类可以使用此方法在页面数量改变时调整页面控件的大小”方法sizeForNumberOfPages:
答案 15 :(得分:1)
以Swift 2.0
及以上为例,以下代码可以使用:
pageControl.pageIndicatorTintColor = UIColor.whiteColor()
pageControl.currentPageIndicatorTintColor = UIColor.redColor()
答案 16 :(得分:0)
这是一个Swift 3.0解决方案......你知道你是否可以接受陈述的风险:“修改现有控件的子视图是脆弱的。”
您必须在viewDidAppear()中调用updateDots(),并为页面控件调用valueChanged处理程序。
import UIKit
class CustomImagePageControl: UIPageControl {
let activeImage:UIImage = UIImage(named: "SelectedPage")!
let inactiveImage:UIImage = UIImage(named: "UnselectedPage")!
override func awakeFromNib() {
super.awakeFromNib()
self.pageIndicatorTintColor = UIColor.clear
self.currentPageIndicatorTintColor = UIColor.clear
self.clipsToBounds = false
}
func updateDots() {
var i = 0
for view in self.subviews {
if let imageView = self.imageForSubview(view) {
if i == self.currentPage {
imageView.image = self.activeImage
} else {
imageView.image = self.inactiveImage
}
i = i + 1
} else {
var dotImage = self.inactiveImage
if i == self.currentPage {
dotImage = self.activeImage
}
view.clipsToBounds = false
view.addSubview(UIImageView(image:dotImage))
i = i + 1
}
}
}
fileprivate func imageForSubview(_ view:UIView) -> UIImageView? {
var dot:UIImageView?
if let dotImageView = view as? UIImageView {
dot = dotImageView
} else {
for foundView in view.subviews {
if let imageView = foundView as? UIImageView {
dot = imageView
break
}
}
}
return dot
}
}
答案 17 :(得分:-1)
myView.superview.tintColor = [UIColor colorWithRed:1.0f
green:1.0f blue:1.0f alpha:1.0f];