如何解决由引起的IQKeyboardManager部分页面返回的键盘高度比实际小或最后收到键盘隐藏通知却显示了键盘问题

news/2025/1/16 5:56:03/

部分页面需要显示一个工具栏,当键盘出现时,这个工具栏显示在键盘上方。由于使用了IQKeyboardManager,导致有的页面iOS12.5.6系统的手机出现首次键盘高度比实际低44像素,而iOS14.7.1系统的手机出现首次键盘高度比实际低44像素并且有时出现最后收到键盘隐藏通知但是实际显示了键盘。
收到通知直接设置工具栏的frame,也过于突兀,最好采用做动画的方式显示工具栏,动画完成时再修正键盘高度,这样能部分解决上面的那两个问题。
那键盘的动画时间是0.25秒,可以在键盘通知里获取到这个参数。那键盘的实际高度从哪里获取呢?经过观察View UI Herarchy发现有键盘的页面都有UIInputSetContainerView,键盘的总高度就是UIInputSetHostView的总高度。只是iOS13及跟高的系统,键盘是在第二个窗口的UIInputWindowController中,而比iOS13低的版本在第是哪个窗口的UITextEffectsWindow中。具体的实现如下:
增加键盘显示通知:

        //监听键盘的变化[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyBoardChange:) name:UIKeyboardWillShowNotification object:nil];

键盘通知处理:

- (void)keyBoardChange:(NSNotification *)notification {//获取键盘的高度NSDictionary *userInfo = [notification userInfo];NSValue *aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];CGRect keyboardRect = [aValue CGRectValue];CGFloat height = keyboardRect.size.height;//获取动画时间ICGFloat animationDuration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];NSLog(@"animationDuration:%f,height:%f",animationDuration,height);if(self.keyBoardChangeBlock){self.keyBoardChangeBlock(height, animationDuration);}
}

键盘显示动画与修正:

- (LCCommentToolView *)comTool {if (_comTool == nil) {_comTool  = [[LCCommentToolView alloc] initWithFrame:CGRectMake(0, 0, KScreenW, BaseSize(100))] ;[_comTool setCorner:UIRectCornerTopLeft|UIRectCornerTopRight cornerSize:BaseSize(15) forRect:CGRectMake(0, 0, KScreenW, BaseSize(100))];DYWeakSelf;[_comTool setKeyBoardChangeBlock:^(CGFloat height, CGFloat animationDuration) {if (DYGlobleData.isLogin) {if(animationDuration <= 0){//防范式编程,理论不会出现weakSelf.bgV.hidden = NO;}else{weakSelf.bgV.hidden = (height<=0);[UIView animateWithDuration:animationDuration animations:^{if((height<=0)){[weakSelf.comTool mas_updateConstraints:^(MASConstraintMaker *make) {make.height.mas_equalTo(BaseSize(100));make.width.mas_equalTo(KScreenW);make.bottom.mas_equalTo(BaseSize(100) -(49+(BR_BOTTOM_MARGIN?24:0)));}];[weakSelf.comTool updateCommentTVWithShift:(BaseSize(100) -(49+(BR_BOTTOM_MARGIN?24:0))+(BR_BOTTOM_MARGIN?24:0))];}else{[weakSelf.comTool mas_updateConstraints:^(MASConstraintMaker *make) {make.height.mas_equalTo(BaseSize(100));make.width.mas_equalTo(KScreenW);make.bottom.mas_equalTo(-height);}];[weakSelf.comTool updateCommentTVWithShift:0];}[weakSelf layoutIfNeeded];} completion:^(BOOL finished) {CGFloat keyboardHeight = [weakSelf displayKeyboardDockView];if(keyboardHeight > 0){[weakSelf.comTool mas_updateConstraints:^(MASConstraintMaker *make) {make.height.mas_equalTo(BaseSize(100));make.width.mas_equalTo(KScreenW);make.bottom.mas_equalTo(-keyboardHeight);}];[weakSelf.comTool updateCommentTVWithShift:0];}else{[weakSelf.comTool mas_updateConstraints:^(MASConstraintMaker *make) {make.height.mas_equalTo(BaseSize(100));make.width.mas_equalTo(KScreenW);make.bottom.mas_equalTo(BaseSize(100) -(49+(BR_BOTTOM_MARGIN?24:0)));}];[weakSelf.comTool updateCommentTVWithShift:(BaseSize(100) -(49+(BR_BOTTOM_MARGIN?24:0))+(BR_BOTTOM_MARGIN?24:0))];}[weakSelf layoutIfNeeded];}];}} else {weakSelf.bgV.hidden = YES;[weakSelf.comTool mas_updateConstraints:^(MASConstraintMaker *make) {make.height.mas_equalTo(BaseSize(100));make.width.mas_equalTo(KScreenW);make.bottom.mas_equalTo(BaseSize(100) -(49+(BR_BOTTOM_MARGIN?24:0)));}];[weakSelf.comTool updateCommentTVWithShift:(BaseSize(100) -(49+(BR_BOTTOM_MARGIN?24:0))+(BR_BOTTOM_MARGIN?24:0))];};}];}return _comTool;
}

识别键盘是否在显示和获取键盘高度,键盘高为0.0是键盘隐藏:

- (CGFloat)displayKeyboardDockView{UIWindow *keyboardWindow = [[[UIApplication sharedApplication] windows] objectAtSafeIndex:1];UIView *keyboardContainerView;UIView *keyboardHostView;if (@available(iOS 13.0, *)){for(int i = 0; i < [keyboardWindow.subviews count]; i++) {keyboardContainerView = [keyboardWindow.subviews objectAtIndex:i];UIViewController *nextResponder = (UIViewController*)[keyboardContainerView nextResponder];if(([nextResponder isKindOfClass:NSClassFromString(@"UIWindow")])){NSLog(@"[nextResponder.subviews count]:%d, nextResponder.subviews:%@", [keyboardWindow.subviews count], keyboardWindow.subviews);}//寻找keyboardWindow层的UIInputWindowControllerelse if ([nextResponder isKindOfClass:NSClassFromString(@"UIInputWindowController")]) {for(int y = 0; y < [nextResponder.view.subviews count]; y++) {//寻找UIInputWindowController层的UIInputSetContainerViewif([[keyboardContainerView description] hasPrefix:@"<UIInputSetContainerView"] == YES){for(int t = 0; t < [keyboardContainerView.subviews count]; t++) {keyboardHostView = [keyboardContainerView.subviews objectAtIndex:t];//寻找UIInputSetContainerView层的UIInputSetHostViewif([[keyboardHostView description] hasPrefix:@"<UIInputSetHostView"] == YES){NSLog(@"keyboardHostView description:%@,keyboardHostView.isHidden:%d,[keyboardHostView.subviews count],[keyboardHostView.subviews count],keyboardHostView.frame.size.height:%f,keyboardHostView.frame.origin.y:%f, (keyboardHostView.frame.origin.y == [[UIScreen mainScreen] bounds].size.height):%d", [keyboardHostView description],keyboardHostView.isHidden,[keyboardHostView.subviews count], keyboardHostView.frame.size.height,keyboardHostView.frame.origin.y, (keyboardHostView.frame.origin.y == [[UIScreen mainScreen] bounds].size.height));if (lroundl(keyboardHostView.frame.origin.y) != lroundl(([[UIScreen mainScreen] bounds].size.height))){return keyboardHostView.frame.size.height;}else{return 0.0;}}}}}}}return 0.0;}else{keyboardWindow = [[[UIApplication sharedApplication] windows] objectAtSafeIndex:2];if(keyboardWindow && [keyboardWindow isKindOfClass:NSClassFromString(@"UITextEffectsWindow")] && !isCommonUnitEmptyArray(keyboardWindow.subviews)){keyboardContainerView = [keyboardWindow.subviews objectAtSafeIndex:0];if(keyboardContainerView && ([[keyboardContainerView description] hasPrefix:@"<UIInputSetContainerView"] == YES)){for(int t = 0; t < [keyboardContainerView.subviews count]; t++) {keyboardHostView = [keyboardContainerView.subviews objectAtIndex:t];//寻找UIInputSetContainerView层的UIInputSetHostViewif([[keyboardHostView description] hasPrefix:@"<UIInputSetHostView"] == YES){NSLog(@"keyboardHostView description:%@,keyboardHostView.isHidden:%d,[keyboardHostView.subviews count],[keyboardHostView.subviews count],keyboardHostView.frame.size.height:%f,keyboardHostView.frame.origin.y:%f, (keyboardHostView.frame.origin.y == [[UIScreen mainScreen] bounds].size.height):%d", [keyboardHostView description],keyboardHostView.isHidden,[keyboardHostView.subviews count], keyboardHostView.frame.size.height,keyboardHostView.frame.origin.y, (keyboardHostView.frame.origin.y == [[UIScreen mainScreen] bounds].size.height));if (lroundl(keyboardHostView.frame.origin.y) != lroundl(([[UIScreen mainScreen] bounds].size.height))){return keyboardHostView.frame.size.height;}else{return 0.0;}}}}}return 0.0;}}

http://www.ppmy.cn/news/745302.html

相关文章

C++ 训练题目

由计算机“想”一个四位数&#xff0c;请人猜这个四位数是多少。人输入四位数字后&#xff0c;计算机首先 判断这四位数字中有几位是猜对了&#xff0c;并且在对的数字中又有几位位置也是对的&#xff0c;将结果显示出来&#xff0c;给人以提示&#xff0c;请人再猜&#xff0c…

SQL-每日一题【511.游戏玩法分析Ⅰ】

题目 活动表 Activity&#xff1a; 写一条 SQL 查询语句获取每位玩家 第一次登陆平台的日期。 查询结果的格式如下所示&#xff1a; 解题思路 前置知识 MIN&#xff08;&#xff09;函数 MIN 函数返回一列中的最小值。NULL 值不包括在计算中。 SQL MIN() 语法 SELECT MIN(co…

[渝粤教育] 扬州工业职业技术学院 “胖集”陪你环游“一带一路” 参考 资料

教育 -“胖集”陪你环游“一带一路”-章节资料考试资料-扬州工业职业技术学院【】 一带一路背景下集装箱运输的机遇与挑战 1、“一带一路”下的集装箱运输 1、【判断题】丝绸之路的命名是因为丝绸位最具代表性的货物。 A、正确 B、错误 参考资料【 】 2、【判断题】“一带一路”…

学术文献翻译改写 F36(含心得)

第36章 英国的天然气市场 本章介绍英国天然气市场,旨在让读者了解这种大宗交易商品的价格决定因素,这里的天然气是指英国国家平衡点(NBP)市场上实货和金融合约形式的天然气。我们重点关注生产、运输和消费的基本面状况与市场体制安排之间的关系。我们发现,虽然天然气的消费对天…

怎么用显卡计算_砖用量、砂浆用了怎么计算,终于搞明白了!!

给你一个每立方砖墙砖消耗量公式&#xff0c;利用这个公式可以计算各种墙厚的砖消耗量&#xff1a; 砖净用量&#xff1d;1/(墙厚*(砖长灰缝)*(砖厚灰缝))*KK-墙厚的砖数*2&#xff1b;墙厚的砖数指&#xff1a;0.5、1、1.5、2、2.5、3&#xff1b; 240墙一方用多少块砖(灰缝取…

怎么用显卡计算_砖用量、砂浆用了怎么计算,终于搞明白了

给你一个每立方砖墙砖消耗量公式&#xff0c;利用这个公式可以计算各种墙厚的砖消耗量&#xff1a; 砖净用量&#xff1d;1/(墙厚*(砖长灰缝)*(砖厚灰缝))*KK-墙厚的砖数*2&#xff1b;墙厚的砖数指&#xff1a;0.5、1、1.5、2、2.5、3&#xff1b; 240墙一方用多少块砖(灰缝取…

超高住宅之殇:美景难抵“鸡肋命”

“前一段工作情况来看&#xff0c;清理这些短视频的违规信息就有6万多条&#xff0c;关闭违规直播间1174个&#xff0c;关闭违规账号3609个&#xff0c;还是取得了一些成绩。” 5月8日&#xff0c;国家互联网信息办公室网络综合治理局局长张拥军&#xff0c;正在介绍2021年“清…

Unity3d学习日记 (1)为场景内物体添加基本逻辑和脚本代码

1.准备:配置Unity3d环境和用VS2019写C#脚本 首先,配置Unity3d环境推荐使用是UnityHub作为平台,然后在UnityHub里边下载Unity3D版本,笔者这里选用的的是2019.4.16f1c1版本,值得注意的是由于Unity给的人机认证邮件的图片源是google的&#xff0c;因此注册的时候是需要翻墙的&…