案例:
UISeachBar的Placeholder上移问题,如下图
分析:
UISeachBar是系统控件未改动过, 所有要修改系统控件.
UISearchBar并未提供相关API来修改位置.
UITextField侧提供一下API供重写:
- (CGRect)placeholderRectForBounds:(CGRect)bounds;
- (void)drawPlaceholderInRect:(CGRect)rect;
解决:
建立UISeachBar子类,从而获取到UISeachBar的子视图UITextField,然后重写
- (CGRect)placeholderRectForBounds:(CGRect)bounds;
建立UITextField的分类,placeHolder偏移接口
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
SEL originalSelector = @selector(placeholderRectForBounds:);
SEL swizzledSelector = @selector(swizzled_placeholderRectForBounds:);
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
BOOL didAddMethod = class_addMethod(class, swizzledSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (!didAddMethod) {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
});
}
- (CGRect)swizzled_placeholderRectForBounds:(CGRect)rect
{
CGRect newRect = rect;
newRect.origin.y += self.placeHolderOffsetY;
return [self swizzled_placeholderRectForBounds:newRect];
}
- (void)setPlaceHolderOffsetY:(float)offsetY {
objc_setAssociatedObject(self, @selector(placeHolderOffsetY), @(offsetY), OBJC_ASSOCIATION_ASSIGN);
}
- (float)placeHolderOffsetY {
NSNumber *typeNum = objc_getAssociatedObject(self, _cmd);
return typeNum.floatValue;
}
在子类(例如LMSearchBar)设置placeHolderOffsetY.
- (void)layoutSubviews {
[self adaptAppearance];
[super layoutSubviews];
}
- (void)adaptAppearance {
UITextField*searchField = [self valueForKey:@"_searchField"];
if (searchField) {
searchField.placeHolderOffsetY = 1;
}
}
这里有个系统问题,iOS8系统会崩溃,要改成OBJC_ASSOCIATION_RETAIN_NONATOMIC
,
验证了浮点型都有这个问题:
- (void)setPlaceHolderOffsetY:(float)offsetY {
objc_setAssociatedObject(self, @selector(placeHolderOffsetY), @(offsetY),OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (float)placeHolderOffsetY {
NSNumber *typeNum = objc_getAssociatedObject(self, _cmd);
return typeNum.floatValue;
}
修改后如图:
demo戳我