没有前言,就是一个简单的键盘监听,自动调整输入框的位置不被键盘遮挡


.h

//
// JYKeyBoardListener.h
//
// Created by JianF.Sun on 17/9/26.
// Copyright © 2017年 sjf. All rights reserved.
//
/*
功能:
1、输入框被键盘遮挡时,整个view上移(此时输入框在键盘上方)
2、键盘弹出时,添加一个按钮负责隐藏键盘
3、禁止某控制器使用JYKeyBoardListener
使用:
1、引入JYKeyBoardListener.h
2、程序启动时:[JYKeyBoardListener useJYKeyboardListener];
3、某些控制器不想使用时:[JYKeyBoardListener unUsedIn:vc];
处理:
1、监听键盘 显示,隐藏,退到后台,进入前台;
2、获取当前顶层控制器;
3、获取当前编辑的输入框在self.view中的frame;
4、键盘显示隐藏时动画;
5、隐藏键盘的按钮添加
6、处理push、present时键盘的显示隐藏问题(切记push之前,代码endEditing,因为push操作系统不会自动退出键盘)
7、处理self.view比屏幕小的问题(即self.view没有伸缩到导航栏底部)
8、处理输入框显示在屏幕中不完整的情况 */
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface JYKeyBoardListener : NSObject
//程序启动时调用
+ (void)useJYKeyboardListener;
//在viewcontroller中禁止使用JYKeyBoardListener
+ (void)unUsedIn:(UIViewController*)viewController;
@end

.m

//
// JYKeyBoardListener.m
//
// Created by JianF.Sun on 17/9/26.
// Copyright © 2017年 sjf. All rights reserved.
// #import "JYKeyBoardListener.h" #define KBL_Screen_Height [UIScreen mainScreen].bounds.size.height NSString * const JYKeyboard_Unused_Key= @"JYKeyboard_Unused_Key"; @interface JYKeyBoardListener ()
@property (nonatomic,strong) UIView *inputView;
@property (nonatomic,strong) UIButton *resignBtn;
@property (nonatomic,strong) UIView *lastView;//记录之前一个需要处理的view,解决push,present操作时,键盘的隐藏问题
//@property (nonatomic,strong) UIViewController *unUsedVC; @end
@implementation JYKeyBoardListener #pragma mark - 接口方法,直接调用即可
+ (void)useJYKeyboardListener{ [JYKeyBoardListener shareJYKeyBoardListener];
}
+ (void)unUsedIn:(UIViewController*)viewController{ JYKeyBoardListener *manager = [JYKeyBoardListener shareJYKeyBoardListener];
[[NSUserDefaults standardUserDefaults] setValue:[manager getMemory:viewController] forKey:JYKeyboard_Unused_Key];
} #pragma mark - 单例 + (instancetype)shareJYKeyBoardListener { static JYKeyBoardListener *jyKeyBoardListener = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
jyKeyBoardListener = [[JYKeyBoardListener alloc] init];
// 监听键盘 [[NSNotificationCenter defaultCenter] addObserver:jyKeyBoardListener selector:@selector(keyboardWillShowAction:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:jyKeyBoardListener selector:@selector(keyboardWillHideAction:) name:UIKeyboardWillHideNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:jyKeyBoardListener selector:@selector(enterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:jyKeyBoardListener selector:@selector(enterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
}); return jyKeyBoardListener;
} #pragma mark - 键盘显示和隐藏的监听方法
/**
* 键盘即将弹出
*/
- (void)keyboardWillShowAction:(NSNotification *)note{ if ([self currentMemory]!=nil&&[[self currentMemory] isEqualToString:[self getMemory:[self topViewController]]]) {
[self addResignBtn:[self topViewController].view];
return;
}else{
[[NSUserDefaults standardUserDefaults] setValue:nil forKey:JYKeyboard_Unused_Key];
} //结束时键盘的frame
CGRect endF = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
//键盘高度
CGFloat keyboardH = endF.size.height;
//键盘弹出需要的时间
CGFloat duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
//当前的view
UIView *firstRspView = [self findFirstResponsderView]; if (firstRspView==nil) {
// NSLog(@"为空");
return ;
}
//找到输入框
[self findSubView:firstRspView]; //获取输入框相对于当前展示的最底层的那个view的frame
CGRect inputFrame = [self getAbsoluteFrame:self.inputView];
//
CGFloat difH = CGRectGetMaxY(inputFrame)-(KBL_Screen_Height-keyboardH);
// 2.动画
[UIView animateWithDuration:duration animations:^{ if (difH>) { firstRspView.transform = CGAffineTransformMakeTranslation(,-difH); }else{
firstRspView.transform = CGAffineTransformIdentity; }
_lastView = firstRspView;
}completion:^(BOOL finished) {
[self addResignBtn:firstRspView]; } ];
}
/**
* 键盘即将隐藏
*/
- (void)keyboardWillHideAction:(NSNotification *)note{ //判断当前控制器是否被禁用
if ([self currentMemory]!=nil&&[[self currentMemory] isEqualToString:[self getMemory:[self topViewController]]]) { return;
}else{
[[NSUserDefaults standardUserDefaults] setValue:nil forKey:JYKeyboard_Unused_Key];
}
// 1.键盘弹出需要的时间
CGFloat duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
UIView *firstRspView = [self findFirstResponsderView]; if(firstRspView==nil){
return;
}
if (_lastView&&_lastView!=firstRspView) {//处理跳转时恢复之前的,push之前必须 _lastView.transform = CGAffineTransformIdentity;
_lastView = nil;
return;
}
// 2.动画
[UIView animateWithDuration:duration animations:^{
firstRspView.transform = CGAffineTransformIdentity; }completion:^(BOOL finished) { }]; } #pragma mark - 前台后台切换处理
- (void)enterBackground:(NSNotification*)note{
[[self findFirstResponsderView] endEditing:YES];
}
- (void)enterForeground:(NSNotification*)note{ }
#pragma mark - 隐藏键盘按钮
- (void)addResignBtn:(UIView*)firstRspView{
if (self.resignBtn) {
[self.resignBtn removeFromSuperview];
}
self.resignBtn = [UIButton buttonWithType:UIButtonTypeCustom];
self.resignBtn.backgroundColor = [UIColor clearColor];
[self.resignBtn addTarget:self action:@selector(hideKeyboard) forControlEvents:UIControlEventTouchUpInside];
self.resignBtn.frame = firstRspView.bounds;
[firstRspView addSubview:self.resignBtn];
[firstRspView sendSubviewToBack:self.resignBtn];
}
- (void)hideKeyboard{
[[self findFirstResponsderView] endEditing:YES];
dispatch_async(dispatch_get_main_queue(), ^{
[self.resignBtn removeFromSuperview]; });
}
#pragma mark - 其他辅助性方法
/**
查找根控制器的view @return return FirstResponsderView
*/
- (UIView*)findFirstResponsderView{ UIViewController *returnVC; //查找当前的根控制器
returnVC = [self topViewController];
if (returnVC) {
return returnVC.view;
}else{
return nil;
}
}
// 获取当前屏幕显示的ViewController
- (UIViewController *)topViewController {
UIViewController *resultVC;
resultVC = [self _topViewController:[[UIApplication sharedApplication].keyWindow rootViewController]];
while (resultVC.presentedViewController) {
resultVC = [self _topViewController:resultVC.presentedViewController];
}
return resultVC;
} - (UIViewController *)_topViewController:(UIViewController *)vc {
if ([vc isKindOfClass:[UINavigationController class]]) {
return [self _topViewController:[(UINavigationController *)vc topViewController]];
} else if ([vc isKindOfClass:[UITabBarController class]]) {
return [self _topViewController:[(UITabBarController *)vc selectedViewController]];
} else {
return vc;
}
return nil;
} /*
获取输入框的相对于根控制器view的frame
*/
- (CGRect)getAbsoluteFrame:(UIView*)view{ UIView *mainView = [self findFirstResponsderView];
UIWindow *window = [UIApplication sharedApplication].keyWindow;
CGRect rect=[view convertRect: view.bounds toView:mainView];
//处理导航栏问题
if (CGRectGetHeight(mainView.bounds)<CGRectGetHeight(window.bounds)) {
rect.origin.y += CGRectGetHeight(window.bounds)-CGRectGetHeight(mainView.bounds);
}
//滚动视图返回的frame去掉scrollView.contentOffset.y
if ([mainView isKindOfClass:[UIScrollView class]]||[mainView isKindOfClass:[UITableView class]]||[mainView isKindOfClass:[UIWebView class]]) {
UIScrollView *scrollView = (UIScrollView*)mainView;
rect.origin.y -=scrollView.contentOffset.y;
if (CGRectGetMaxY(rect)>KBL_Screen_Height) {//输入框没有完全显示出来 //去掉屏幕外的高度值
rect.origin.y-=CGRectGetMaxY(rect)-KBL_Screen_Height;
}
} return rect;
} /*
递归法
找到输入框
*/
- (void)findSubView:(UIView*)view{ for (UIView *subView in view.subviews){ if ([subView isFirstResponder]) {
// NSLog(@"找到输入框");
self.inputView = subView;
}else{
[self findSubView:subView];
}
}
} - (NSString*)getMemory:(UIViewController*)vc{
//控制器名称+内容的内存地址+view的内容地址
return [NSString stringWithFormat:@"jykeyboard%@%p%p",NSStringFromClass([vc class]),vc,vc.view];
}
- (NSString*)currentMemory{
return [[NSUserDefaults standardUserDefaults] valueForKey:JYKeyboard_Unused_Key];
}
@end

ios --键盘监听JYKeyBoardListener的更多相关文章

  1. iOS键盘监听事件

    1.注册键盘通知事件 NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; // 键盘将出现事件监听 [center ...

  2. iOS键盘监听的通知

    #pragma mark - 键盘通知回调方法 //  监听键盘的通知 [[NSNotificationCenter defaultCenter] addObserver:self selector: ...

  3. js 获取当前焦点所在的元素、给元素和input控件添加键盘监听事件、添加页面级的键盘监听事件

    页面级的键盘监听事件 document.onkeydown = function (event) { var e = event || window.event || arguments.callee ...

  4. 使用HTML+CSS,jQuery编写的简易计算器后续(添加了键盘监听)

    之前发布了一款简易的计算器,今天做了一下修改,添加了键盘监听事件,不用再用鼠标点点点啦 JS代码: var yunSuan = 0;// 运算符号,0-无运算;1-加法;2-减法;3-乘法;4-除法 ...

  5. [置顶] java Gui 键盘监听事件

    简单写一个java Gui键盘监听事件,实现的效果就是按下键盘控制台输出你按下的键.比如:按下A控制台就输出A 效果如图: 以下把实现的效果分为几个步骤: 1.新建一个窗体类继承窗体: 2.给这个窗体 ...

  6. java swing button和键盘监听冲突问题

    原因: 点击button会让jframe失去焦点,然后键盘监听不起作用 解决: 让jframe重新获取焦点就行了 jf.setFocusable(true); // JFrame jf = new J ...

  7. JPanel添加键盘监听事件

    因为在自己的游戏需求中谢了要用键盘控制飞机的移动,所以用到键盘监听事件,但是使用了JPanel之后添加了键盘监听事件,按相应的方向键飞机并没有反应.但是如果是为JFrame的内容面板加则会有反应. 为 ...

  8. C#全局键盘监听(Hook)

    一.为什么需要全局键盘监听? 在某些情况下应用程序需要实现快捷键执行特定功能,例如大家熟知的QQ截图功能Ctrl+Alt+A快捷键,只要QQ程序在运行(无论是拥有焦点还是处于后台运行状态),都可以按下 ...

  9. 【转】【C#】全局键盘监听

    using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServi ...

随机推荐

  1. android资源文件

    代码与资源分离原则:便于维护与修改shape:定义图形 selector:按照不同的情况加载不同的color或drawable layer-list:从下往上图形层叠加载 资源文件有:/res/dra ...

  2. opentwebst一个ie自动化操作测试软件-功能强大

    opentwebst一个ie自动化操作测试软件-功能强大 一个ie自动化操作测试软件,自动根据操作记录脚本.生成vbs,js和其他脚本语言,用来运行 里面包含了两个东西: 1.脚本操作自动记录,记录下 ...

  3. Error:(18, 51) java: -source 1.5 中不支持 diamond 运算符 (请使用 -source 7 或更高版本以启用 diamond 运算符)

    问题:主要是因为jdk版本不一样 解决: 方法一:List<String> list=new ArrayList<Stirng>(); 方法二:重新安装jdk8的版本(安装和配 ...

  4. Transport Layer Protocols

    1 End-to-end Protocols(端到端协议) 传输层协议往往是主机对主机(host-to-host)或者说是端到端(end-to-end).通常希望传输层协议可以提供如下service: ...

  5. pyg 图片服务器中使用的nginx 编译位置

    ./nginx 启动

  6. 玩玩vs Git 中国版 Gitee

    下载vs  下载 Gitee.VisualStudio.vsix https://gitee.com/GitGroup/CodeCloud.VisualStudio/attach_files 去git ...

  7. grid布局学习二之子元素(项目)

    /* grid-column-start属性:左边框所在的垂直网格线 grid-column-end属性:右边框所在的垂直网格线 grid-row-start属性:上边框所在的水平网格线 grid-r ...

  8. 安装过redis集群,重新做集群办法:

    二:找到问题:这个地方IP的问题,以上是正确的版本,以前有问题的版本的Ip是127.0.0.1, 原因是这个地方以前我没注释redis.conf文件中的bind 127.0.0.1 然后做集群时使用的 ...

  9. 基于httpclient的效率优化

    1.背景 我们有个业务,会调用其他部门提供的一个基于http的服务,日调用量在千万级别.使用了httpclient来完成业务.之前因为qps上不去,就看了一下业务代码,并做了一些优化,记录在这里. 先 ...

  10. 【DB2】Event monitor for locking

    Customer said, they got the following Errors in applications logs Caused by: financing.tools.hub.sha ...