當我們在開發過程中相信很多人遇到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就會被替換。自動會解決向下便宜的問題。