iOS UITextField輸入框內容向下便宜

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章