当我们在开发过程中相信很多人遇到UITextField内容向下便宜的现象,这个现象出现的版本是iOS10以上的问题,那我们要如何处理便宜呢。网上有很多解决方案,但是我感觉都不是很完美,因为他不能从根本上解决这个问题。知道我在网上找到了一个博客才发现这个方法,可以从根本上解决。
大家都知道OC是一个面向对象的语言,他的方法等实现本质都是通知,而实现就是通过runtime实现,runtime可以说是OC语音的底层实现,Runtime是iOS的核心之一,我们写的OC代码底层都是由他实现的,经过遍译后,都是Runtime形式的C语言代码。
为什么我这里要说这些呢,UITextField解决下移方式,就是通过runtime来实现的,从底层解决所有问题。好了废话不多说下面直接上代码,实现的方式是个类别。
首先展示的是.h文件,.h文件没有任何内容
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UITextField (Fix)
@end
NS_ASSUME_NONNULL_END
接下来是.m
#import "UITextField+Fix.h"
#import <objc/runtime.h>
@implementation UITextField (Fix)
void swizzleMethod(Class class,SEL originalSelector,SEL swizzledSelector){
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
if(didAddMethod){
class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
}else{
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
+ (void)load
{
CGFloat systemVersion = [[UIDevice currentDevice].systemVersion floatValue];
if(systemVersion >= 10.0 && systemVersion < 11.0){
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
swizzleMethod(class, @selector(layoutSubviews), @selector(yl_layoutSubviews));
});
}
}
- (void)yl_layoutSubviews
{
[self yl_layoutSubviews];
for(UIScrollView *view in self.subviews){
if([view isKindOfClass:[UIScrollView class]]){
CGPoint offset = view.contentOffset;
if(offset.y != 0) {
offset.y = 0;
view.contentOffset = offset;
}
break;
}
}
}
@end
然后将这个类别放入到工程即可,看到这里可能还是很懵,这里下面的方法就是Runtime提供的方法,这个方法是底层代码,在这我们可以直接将向下便宜代码替换掉,换成新的Method
void swizzleMethod(Class class,SEL originalSelector,SEL swizzledSelector)
+ (void)load
是每当创建UITextField都是调用的,在这里我们在每次使用UITextField都会处理一下,当调用
+ (void)load
方法时,如果系统版本大于iOS10,就会调用下面方法
swizzleMethod(Class class,SEL originalSelector,SEL swizzledSelector)
当系统版本大于iOS10,就会有新的Method swizzledMethod,替换或者交换老的Method originalMethod,这样当执行这个方法,旧的Method就会被替换。自动会解决向下便宜的问题。