iOS系统中,UIPageControl默认的样式如下:
在业务开发过程中,很多时候都需要自定义UIPageControl圆点的展示样式及圆点之间的间隔。在网上搜索了如何自定义UIPageControl,比比皆是下面的实现方式:
//自定义一个UIPageControl的子类
-(void) updateDots
{
for (int i = 0; i < [self.subviews count]; i++)
{
UIImageView* dot = [self.subviews objectAtIndex:i];
if (i == self.currentPage) {
if(i==0) {
dot.image = [UIImage imageNamed:@"activesearch.png"];
} else {
dot.image = activeImage;
}
} else {
if(i==0) {
dot.image = [UIImage imageNamed:@"inactivesearch.png"];
} else {
dot.image = inactiveImage;
}
}
}
}
-(void)setCurrentPage:(NSInteger)page
{
[super setCurrentPage:page];
[self updateDots];
}
但是将其运用到实践中,会引起崩溃,原因是UIPageControl subviews中的对象并不是UIImageView的实例,而是UIView的实例。
系统是如何实现的?
遍历subviews数组:
for (int i = self.subviews.count - 1; i >= 0; --i) {
UIView *dotView = [self.subviews objectAtIndex:i]; }
打印dotView:
<UIView: 0x7fa47ae99ab0; frame = (193 1.5; 7 7); layer = <CALayer: 0x6080004321a0>>
从中只能看见frame信息,并不知道原点样式是如何设置的,进一步打印dotView.layer:
//非活动态
<CALayer:0x6080004321a0; position = CGPoint (196.5 5); bounds = CGRect (0 0; 7 7); delegate = <UIView: 0x7fa47ae99ab0; frame = (193 1.5; 7 7); layer = <CALayer: 0x6080004321a0>>; opaque = YES; allowsGroupOpacity = YES; cornerRadius = 3.5; backgroundColor = <CGColor 0x60800029ed20> [<CGColorSpace 0x608000036320> (kCGColorSpaceICCBased; kCGColorSpaceModelMonochrome; 普通灰度系数 2.2 描述文件; extended range)] ( 1 0.2 )>
//活动态
<CALayer:0x6000004286c0; position = CGPoint (0 0); bounds = CGRect (0 0; 7 7); delegate = <UIView: 0x7ff7b8c87e30; frame = (-3.5 -3.5; 7 7); layer = <CALayer: 0x6000004286c0>>; opaque = YES; allowsGroupOpacity = YES; cornerRadius = 3.5; backgroundColor = <CGColor 0x6000000952c0> [<CGColorSpace 0x600000227120> (kCGColorSpaceICCBased; kCGColorSpaceModelMonochrome; 普通灰度系数 2.2 描述文件; extended range)] ( 1 1 )>
layer的宽高为7,cornerRadius为3.5,非活动态时backgroundColor的alpha = 0.2,活动态时alpha = 1。这就解释了系统的样式为什么是圆点和其活动态和非活动态下的透明度。从而得到思路可以修改UIPageControl子view的layer来修改样式。
自定义实现
自定义CustomCyclePageControl继承自UIPageControl
.h文件:
#import <UIKit/UIKit.h>
@interface CustomCyclePageControl : UIPageControl
@property (nonatomic, strong) UIImage *activeDotImage;
@property (nonatomic, strong) UIImage *inActiveDotImage;
@end
.m文件:
#import "CustomCyclePageControl.h"
@interface CustomCyclePageControl ()
@property (nonatomic, assign) NSInteger lastActivePage;
@end
@implementation CustomCyclePageControl
- (void)updateDots {
if (self.subviews.count > self.currentPage) {
UIView *dotView = [self.subviews objectAtIndex:self.currentPage];
dotView.layer.contents = (id)self.activeDotImage.CGImage;
dotView.layer.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.6f].CGColor;
if (self.lastActivePage != self.currentPage) {
if (self.subviews.count > self.lastSelectedPage) {
dotView = [self.subviews objectAtIndex:self.lastActivePage];
dotView.layer.contents = (id)self.inActiveDotImage.CGImage;
dotView.layer.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.3f].CGColor;
}
}
}
}
- (void)layoutSubviews {
[super layoutSubviews];
if (self.activeDotImage && self.inActiveDotImage) {
CGFloat left = CGRectGetWidth(self.frame) - self.activeDotImage.size.width;
CGFloat right = CGRectGetMaxX(self.frame);
for (int i = self.subviews.count - 1; i >= 0; --i)
{
UIView *dotView = [self.subviews objectAtIndex:i];
dotView.frame = CGRectMake(left, ((CGRectGetHeight(self.frame) - self.inActiveDotImage.size.height) / 2.f), self.inActiveDotImage.size.width, self.inActiveDotImage.size.height);
left -= (4 + self.inActiveDotImage.size.width);
dotView.layer.cornerRadius = 0.5f;
dotView.layer.contents = (id)self.inActiveDotImage.CGImage;
dotView.layer.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.3f].CGColor;
}
}
}
- (void)setCurrentPage:(NSInteger)currentPage {
[super setCurrentPage:currentPage];
if (self.activeDotImage && self.inActiveDotImage) {
[self updateDots];
self.lastActivePage = currentPage;
}
}
@end
注意:自定义时activeDotImage,inActiveDotImage都不能为nil。
自定义之后的样式: