iOS解决键盘遮挡的神器

注:代码并非原创,以前找帖子拿来用的忘记原贴了。只是留个笔记,非原创勿喷

  • 主要思路通过UIResponder类别拦截,init方法注册键盘打开关闭的方法。然后实现相关的逻辑计算遮挡部分的高度,调整坐标解决遮挡

代码

#import <UIKit/UIKit.h>

@interface UIResponder (BGKeyboardMgr)

@end

#import "UIResponder+BGKeyboardMgr.h"
#import <objc/runtime.h>



static CGRect initFrame;
static UIButton *endButton=nil;

#define MainWindow [[UIApplication sharedApplication].delegate window]

#define IsEvent [self isKindOfClass:[UITextField class]]||[self isKindOfClass:[UITextView class]]


@implementation UIResponder (BGKeyboardMgr)

/**
 
 实现UIResponder
 
 **/

-(instancetype)init {
    
    if (self=[super init]) {
        [self registerKeyboardManagement];//注册键盘的监听
    }
    return self;
    
}

#pragma mark - ============ 其他 ============
/**
 
 注册键盘的监听
 
 **/
-(void)registerKeyboardManagement {
    if (IsEvent) {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardNotificationAction:) name:UIKeyboardWillHideNotification object:nil];
        
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardNotificationAction:) name:UIKeyboardWillShowNotification object:nil];
    }
}

-(void)dealloc {
    if (IsEvent) {
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    }
}

#pragma mark - ============ 给类触发事件 ============

#pragma mark - 键盘通知

- (void)keyboardNotificationAction:(NSNotification *)notification {
    
    if (!self.isFirstResponder) {
        
    } else {
        if ([notification.name isEqualToString:UIKeyboardWillHideNotification]) {
            UIView *view =[MainWindow.subviews objectAtIndex:0];
            NSValue *value =[NSValue valueWithCGRect:initFrame];
            if (!([value isEqualToValue:[NSValue valueWithCGRect:CGRectNull]]||[value isEqualToValue:[NSValue valueWithCGRect:CGRectZero]])) {
                view.frame=initFrame;
                initFrame=CGRectZero;
            }
            [endButton removeFromSuperview];
            MainWindow.backgroundColor=[UIColor clearColor];
            
        }
        else if ([notification.name isEqualToString:UIKeyboardWillShowNotification]) {
            CGRect keyboardFrame = ((NSValue *) notification.userInfo[UIKeyboardFrameEndUserInfoKey]).CGRectValue;
            UIView *sfView=(UIView*)self;
            
            /**
             
             计算输入框相对于MainWindow的位置
             
             **/
            
            CGRect rect =[MainWindow convertRect:sfView.frame fromView:sfView.superview];
            CGFloat tfMaxY = rect.origin.y+rect.size.height;
            if (rect.origin.y<kScreenHeight-49) {
                tfMaxY = tfMaxY>kScreenHeight?kScreenHeight-49-22:tfMaxY;
            }else {
                tfMaxY = tfMaxY>kScreenHeight?kScreenHeight:tfMaxY;
            }
            CGFloat y=tfMaxY-keyboardFrame.origin.y;
            UIView *view =[MainWindow.subviews objectAtIndex:0];
            NSValue *value =[NSValue valueWithCGRect:initFrame];
            if ([value isEqualToValue:[NSValue valueWithCGRect:CGRectNull]]||[value isEqualToValue:[NSValue valueWithCGRect:CGRectZero]]) {
                initFrame=view.frame;
            }
            if (!endButton) {
                endButton=[UIButton buttonWithType:UIButtonTypeSystem];
                endButton.frame=CGRectMake(keyboardFrame.size.width-69, keyboardFrame.origin.y-22, 64, 22);
                endButton.contentHorizontalAlignment=UIControlContentHorizontalAlignmentRight;
                [endButton setTitle:@"结束编辑" forState:UIControlStateNormal];
                endButton.titleLabel.font=[UIFont systemFontOfSize:15.0f];
                [endButton addTarget:MainWindow action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
            }
            [MainWindow addSubview:endButton];
            MainWindow.backgroundColor=[UIColor whiteColor];
            if (y>0) {
                view.y = view.y-y-endButton.height;
//                view.frame=CGRectMake(view.frame.origin.x, view.frame.origin.y-y-endButton.frame.size.height, view.frame.size.width, view.frame.size.height);
            }
        }
    }
}

#pragma mark - buttonAction

-(void)buttonAction:(UIButton *)sender {
    [MainWindow endEditing:YES];
}

@end

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,252评论 6 516
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,886评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,814评论 0 361
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,869评论 1 299
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,888评论 6 398
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,475评论 1 312
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,010评论 3 422
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,924评论 0 277
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,469评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,552评论 3 342
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,680评论 1 353
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,362评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,037评论 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,519评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,621评论 1 274
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,099评论 3 378
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,691评论 2 361

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,312评论 25 707
  • 在开发过程中,大家或多或少的都会碰到令人头疼的手势冲突问题,正好前两天碰到一个类似的bug,于是借着这个机会了解了...
    闫仕伟阅读 5,359评论 2 23
  • 循环引用:http://ios.jobbole.com/82077/类别的作用功能:1.扩充现有类的功能2.对现有...
    得一切从简阅读 503评论 0 1
  • 37.cocoa内存管理规则 1)当你使用new,alloc或copy方法创建一个对象时,该对象的保留计数器值为1...
    如风家的秘密阅读 856评论 0 4
  • 五月的微风混杂着 柠檬味汽水 飘扬的白衬衫 露齿的笑 我站在风口 我的世界满是你的味道 周二上午十点的篮球场 周三...
    姜海苔阅读 426评论 5 3