今天遇到这个需求,需要修改UIPageControl圆点之间的间距。查资料找到以下两种方法,其一是自定义继承UIPageControl的类,其二是使用runtime交换方法来修改。
文笔不好直接代码记录
#import "HYRPageControl.h"
#define kDotW 30 //圆点的宽度
#define kMagrin 20 //圆点之间的间隔
@interface HYRPageControl ()
@end
@implementation HYRPageControl
#pragma mark - 法一
- (void)layoutSubviews
{
[super layoutSubviews];
//计算圆点尺寸和间距的长度
CGFloat marginX = kDotW + kMagrin;
//计算整个pageControll的宽度
CGFloat newW = self.frame.size.width;//(self.subviews.count - 1 ) * magrin + self.subviews.count *dotW;
//计算左边距
CGFloat leftRight = (newW - ((self.subviews.count - 1 ) * kMagrin + self.subviews.count * kDotW)) / 2;
//设置新frame
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, newW, self.frame.size.height);
//遍历subview,设置圆点frame
for (int i=0; i<[self.subviews count]; i++) {
UIImageView* dot = [self.subviews objectAtIndex:i];
[dot setFrame:CGRectMake(i * marginX + leftRight, dot.frame.origin.y, kDotW, kDotW)];
}
}
@end
我本来是在demo中已经输出所有的成员变量了,但是没有发现相关距离的变量。简单看看代码
// runtime:根据模型中属性,去字典中取出对应的value给模型属性赋值
// 1.获取模型中所有成员变量 key
// 获取哪个类的成员变量
// count:成员变量个数
unsigned int count = 0;
// 获取成员变量数组
Ivar *ivarList = class_copyIvarList([UIPageControl class], &count);
for (NSInteger i = 0; i
//runtime 获取所有方法名
unsigned int count = 0;
//获取方法列表
Method *methodList = class_copyMethodList([UIPageControl class], &count);
for (NSInteger i = 0; i < count; i++) {
//
Method method = methodList[i];
SEL sel = method_getName(method);
NSString *methodName = [NSString stringWithUTF8String:sel_getName(sel)];
//返回值类型
char *dst = method_copyReturnType(method);
// size_t dstLen = 512;
// char dst[512] = {};
// method_getReturnType(method, dst, dstLen);
NSLog(@"methodName:%@- retunType:%@",methodName,[NSString stringWithUTF8String:dst]);
}
2017-08-26 21:02:37.377 Runtime修改分页控制器的距离[2794:135521] methodName:.cxx_destruct- retunType:v
2017-08-26 21:02:37.380 Runtime修改分页控制器的距离[2794:135521] methodName:layoutSubviews- retunType:v
2017-08-26 21:02:37.380 Runtime修改分页控制器的距离[2794:135521] methodName:_populateArchivedSubviews:- retunType:v
2017-08-26 21:02:37.381 Runtime修改分页控制器的距离[2794:135521] methodName:_contentHuggingDefault_isUsuallyFixedHeight- retunType:B
2017-08-26 21:02:37.381 Runtime修改分页控制器的距离[2794:135521] methodName:_contentHuggingDefault_isUsuallyFixedWidth- retunType:B
2017-08-26 21:02:37.381 Runtime修改分页控制器的距离[2794:135521] methodName:gestureRecognizerShouldBegin:- retunType:B
2017-08-26 21:02:37.381 Runtime修改分页控制器的距离[2794:135521] methodName:canBecomeFocused- retunType:B
2017-08-26 21:02:37.381 Runtime修改分页控制器的距离[2794:135521] methodName:intrinsicContentSize- retunType:{CGSize=dd}
2017-08-26 21:02:37.382 Runtime修改分页控制器的距离[2794:135521] methodName:_didChangeFromIdiom:onScreen:traverseHierarchy:- retunType:v
2017-08-26 21:02:37.382 Runtime修改分页控制器的距离[2794:135521] methodName:endTrackingWithTouch:withEvent:- retunType:v
2017-08-26 21:02:37.382 Runtime修改分页控制器的距离[2794:135521] methodName:_controlEventsForActionTriggered- retunType:Q
2017-08-26 21:02:37.384 Runtime修改分页控制器的距离[2794:135521] methodName:_effectiveContentView- retunType:@
2017-08-26 21:02:37.384 Runtime修改分页控制器的距离[2794:135521] methodName:setHidesForSinglePage:- retunType:v
2017-08-26 21:02:37.384 Runtime修改分页控制器的距离[2794:135521] methodName:setCurrentPageIndicatorTintColor:- retunType:v
2017-08-26 21:02:37.385 Runtime修改分页控制器的距离[2794:135521] methodName:setPageIndicatorTintColor:- retunType:v
2017-08-26 21:02:37.385 Runtime修改分页控制器的距离[2794:135521] methodName:setNumberOfPages:- retunType:v
2017-08-26 21:02:37.385 Runtime修改分页控制器的距离[2794:135521] methodName:setCurrentPage:- retunType:v
2017-08-26 21:02:37.385 Runtime修改分页控制器的距离[2794:135521] methodName:currentPage- retunType:q
2017-08-26 21:02:37.385 Runtime修改分页控制器的距离[2794:135521] methodName:_pageIndicatorImageForPage:- retunType:@
2017-08-26 21:02:37.385 Runtime修改分页控制器的距离[2794:135521] methodName:_pageIndicatorCurrentImageForPage:- retunType:@
2017-08-26 21:02:37.386 Runtime修改分页控制器的距离[2794:135521] methodName:_commonPageControlInit- retunType:v
2017-08-26 21:02:37.386 Runtime修改分页控制器的距离[2794:135521] methodName:numberOfPages- retunType:q
2017-08-26 21:02:37.386 Runtime修改分页控制器的距离[2794:135521] methodName:_invalidateIndicators- retunType:v
2017-08-26 21:02:37.386 Runtime修改分页控制器的距离[2794:135521] methodName:_activePageIndicatorImage- retunType:@
2017-08-26 21:02:37.386 Runtime修改分页控制器的距离[2794:135521] methodName:_cachedPageIndicatorImageForPage:- retunType:@
2017-08-26 21:02:37.386 Runtime修改分页控制器的距离[2794:135521] methodName:_cachedPageIndicatorCurrentImageForPage:- retunType:@
2017-08-26 21:02:37.387 Runtime修改分页控制器的距离[2794:135521] methodName:_pageIndicatorImage- retunType:@
2017-08-26 21:02:37.387 Runtime修改分页控制器的距离[2794:135521] methodName:_cachePageIndicatorImages- retunType:v
2017-08-26 21:02:37.387 Runtime修改分页控制器的距离[2794:135521] methodName:_indicatorViewEnabled:index:- retunType:@
2017-08-26 21:02:37.387 Runtime修改分页控制器的距离[2794:135521] methodName:_setCurrentPage:- retunType:v
2017-08-26 21:02:37.387 Runtime修改分页控制器的距离[2794:135521] methodName:_setDisplayedPage:- retunType:v
2017-08-26 21:02:37.388 Runtime修改分页控制器的距离[2794:135521] methodName:_updateCurrentPageDisplay- retunType:v
2017-08-26 21:02:37.388 Runtime修改分页控制器的距离[2794:135521] methodName:_indicatorSpacing- retunType:d
2017-08-26 21:02:37.388 Runtime修改分页控制器的距离[2794:135521] methodName:_indicatorFrameAtIndex:- retunType:{CGRect={CGPoint=dd}{CGSize=dd}}
2017-08-26 21:02:37.388 Runtime修改分页控制器的距离[2794:135521] methodName:_hasCustomImageForPage:enabled:- retunType:B
2017-08-26 21:02:37.388 Runtime修改分页控制器的距离[2794:135521] methodName:_modernBounds- retunType:{CGRect={CGPoint=dd}{CGSize=dd}}
2017-08-26 21:02:37.389 Runtime修改分页控制器的距离[2794:135521] methodName:_transitionIndicator:toEnabled:index:- retunType:v
2017-08-26 21:02:37.389 Runtime修改分页控制器的距离[2794:135521] methodName:_modernTransitionIndicator:toEnabled:index:legible:- retunType:v
2017-08-26 21:02:37.389 Runtime修改分页控制器的距离[2794:135521] methodName:_shouldDrawLegibly- retunType:B
2017-08-26 21:02:37.389 Runtime修改分页控制器的距离[2794:135521] methodName:_transitionIndicator:toEnabled:index:legible:- retunType:v
2017-08-26 21:02:37.390 Runtime修改分页控制器的距离[2794:135521] methodName:_indicatorViewEnabled:index:legible:- retunType:@
2017-08-26 21:02:37.390 Runtime修改分页控制器的距离[2794:135521] methodName:_drawModernIndicatorInView:enabled:- retunType:v
2017-08-26 21:02:37.390 Runtime修改分页控制器的距离[2794:135521] methodName:_modernIndicatorImageEnabled:- retunType:@
2017-08-26 21:02:37.390 Runtime修改分页控制器的距离[2794:135521] methodName:_setLegibilitySettings:- retunType:v
2017-08-26 21:02:37.390 Runtime修改分页控制器的距离[2794:135521] methodName:_modernColorEnabled:- retunType:@
2017-08-26 21:02:37.391 Runtime修改分页控制器的距离[2794:135521] methodName:_modernCornerRadius- retunType:d
2017-08-26 21:02:37.391 Runtime修改分页控制器的距离[2794:135521] methodName:_createModernIndicatorImageFromView:- retunType:@
2017-08-26 21:02:37.391 Runtime修改分页控制器的距离[2794:135521] methodName:hidesForSinglePage- retunType:B
2017-08-26 21:02:37.391 Runtime修改分页控制器的距离[2794:135521] methodName:setDefersCurrentPageDisplay:- retunType:v
2017-08-26 21:02:37.392 Runtime修改分页控制器的距离[2794:135521] methodName:defersCurrentPageDisplay- retunType:B
2017-08-26 21:02:37.392 Runtime修改分页控制器的距离[2794:135521] methodName:updateCurrentPageDisplay- retunType:v
2017-08-26 21:02:37.392 Runtime修改分页控制器的距离[2794:135521] methodName:sizeForNumberOfPages:- retunType:{CGSize=dd}
2017-08-26 21:02:37.393 Runtime修改分页控制器的距离[2794:135521] methodName:_displayedPage- retunType:q
2017-08-26 21:02:37.393 Runtime修改分页控制器的距离[2794:135521] methodName:_setLegibilityStyle:- retunType:v
2017-08-26 21:02:37.393 Runtime修改分页控制器的距离[2794:135521] methodName:_legibilityStyle- retunType:q
2017-08-26 21:02:37.393 Runtime修改分页控制器的距离[2794:135521] methodName:currentPageIndicatorTintColor- retunType:@
2017-08-26 21:02:37.394 Runtime修改分页控制器的距离[2794:135521] methodName:pageIndicatorTintColor- retunType:@
2017-08-26 21:02:37.394 Runtime修改分页控制器的距离[2794:135521] methodName:_legibilitySettings- retunType:@
2017-08-26 21:02:37.394 Runtime修改分页控制器的距离[2794:135521] methodName:isElementAccessibilityExposedToInterfaceBuilder- retunType:B
2017-08-26 21:02:37.394 Runtime修改分页控制器的距离[2794:135521] methodName:encodeWithCoder:- retunType:v
2017-08-26 21:02:37.395 Runtime修改分页控制器的距离[2794:135521] methodName:initWithCoder:- retunType:@
2017-08-26 21:02:37.395 Runtime修改分页控制器的距离[2794:135521] methodName:initWithFrame:- retunType:@
2017-08-26 21:02:37.395 Runtime修改分页控制器的距离[2794:135521] methodName:sizeThatFits:- retunType:{CGSize=dd}
找啊找 找啊找 终于让我发现了这个方法
_indicatorSpacing
返回值类型是double
这样的话 我就先在我的控制器里面写一个方法,方法名最好是我们的前缀加上这个私有的方法名,这样一看就可以猜到是什么作用了。
#pragma mark - 自定义方法来实现 圆点之间的距离 利用runtime交换方法
-(CGFloat)hyr_indicatorSpacing{
return 80.0;
}
//runtime 交换方法 实现圆点之间的距离
//系统的方法
Method origin = class_getInstanceMethod([UIPageControl class], sel_registerName("_indicatorSpacing"));
Method custom = class_getInstanceMethod([self class], sel_registerName("hyr_indicatorSpacing"));
//但是调用了私有的API方法,据说上传appstroe会被拒的
method_exchangeImplementations(origin, custom);
运行结果如下: