- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在尝试获取 iOS 键盘的高度。我已经完成并使用了涉及订阅通知的方法,如下所述: https://gist.github.com/philipmcdermott/5183731
- (void)viewDidAppear:(BOOL) animated {
[super viewDidAppear:animated];
// Register notification when the keyboard will be show
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
// Register notification when the keyboard will be hide
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)keyboardWillShow:(NSNotification *)notification {
CGRect keyboardBounds;
[[notification.userInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] getValue:&keyboardBounds];
// Do something with keyboard height
}
- (void)keyboardWillHide:(NSNotification *)notification {
CGRect keyboardBounds;
[[notification.userInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] getValue:&keyboardBounds];
// Do something with keyboard height
}
这在用户实际显示键盘时效果很好。
我的问题:我有另一个 View ,我们称它为 micView,它可能会在键盘出现之前显示。用户可以选择在打字前使用麦克风。我希望 micView 与键盘高度相同,这就是为什么我需要键盘的高度,但在键盘被迫出现之前我需要它。因此,在我需要读取高度值之前,未达到 UIKeyboardWillShowNotification。
我的问题是:如何在不显示键盘的情况下通过通知或其他一些方法获取键盘的高度。
我考虑过明确强制键盘出现在 viewDidLoad 中,这样我就可以将一个实例变量设置为该值,然后隐藏它并摆脱这两种情况的动画。但这真的是唯一的方法吗?
最佳答案
这个 Swift 类提供了一个交 key 解决方案来管理所有必要的通知和初始化,让您只需调用一个类方法并返回键盘大小或高度。
从 Swift 调用:
let keyboardHeight = KeyboardService.keyboardHeight()
let keyboardSize = KeyboardService.keyboardSize()
从 Objective-C 调用:
CGFloat keyboardHeight = [KeyboardService keyboardHeight];
CGRect keyboardSize = [KeyboardService keyboardSize];
如果想将其用于初始 View 布局,请从类的 viewWillAppear
方法中调用此方法,您希望在键盘出现之前获得键盘高度或大小。不应在 viewDidLoad 中调用它,因为正确的值取决于您的 View 布局。然后,您可以使用从 KeyboardService 返回的值设置自动布局约束常量,或以其他方式使用该值。例如,您可能希望在 prepareForSegue
中获取键盘高度,以帮助设置与通过嵌入转场填充的 containerView 的内容关联的值。
注意安全区域、键盘高度和 iPhone X:
键盘高度的值返回键盘的完整高度,在 iPhone X 上它延伸到屏幕本身的边缘,而不仅仅是插入的安全区域。因此,如果使用返回值设置自动布局约束值,则应将该约束附加到父 View 底部边缘,而不是安全区域。
注意模拟器中的硬件键盘:
连接硬件键盘时,此代码将提供该硬件键盘的屏幕高度,即无高度。当然,确实需要考虑这种状态,因为这模拟了将硬件键盘连接到实际设备时会发生的情况。因此,期望键盘高度的布局需要适本地响应零键盘高度。
KeyboardService 类:
与往常一样,如果从 Objective-C 调用,您只需在 Objective-C 类中导入应用程序的 Swift 桥接头文件 MyApp-Swift.h
。
import UIKit
class KeyboardService: NSObject {
static var serviceSingleton = KeyboardService()
var measuredSize: CGRect = CGRect.zero
@objc class func keyboardHeight() -> CGFloat {
let keyboardSize = KeyboardService.keyboardSize()
return keyboardSize.size.height
}
@objc class func keyboardSize() -> CGRect {
return serviceSingleton.measuredSize
}
private func observeKeyboardNotifications() {
let center = NotificationCenter.default
center.addObserver(self, selector: #selector(self.keyboardChange), name: .UIKeyboardDidShow, object: nil)
}
private func observeKeyboard() {
let field = UITextField()
UIApplication.shared.windows.first?.addSubview(field)
field.becomeFirstResponder()
field.resignFirstResponder()
field.removeFromSuperview()
}
@objc private func keyboardChange(_ notification: Notification) {
guard measuredSize == CGRect.zero, let info = notification.userInfo,
let value = info[UIKeyboardFrameEndUserInfoKey] as? NSValue
else { return }
measuredSize = value.cgRectValue
}
override init() {
super.init()
observeKeyboardNotifications()
observeKeyboard()
}
deinit {
NotificationCenter.default.removeObserver(self)
}
}
点头:
此处的 observeKeyboard 方法基于 Peres 在对这个问题的 Objective-C 回答中概述的原始方法。
关于ios - 在不显示键盘的情况下获取iOS键盘的高度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26981261/
我是 Java 新手,这是我的代码, if( a.name == b.name && a.displayname == b.displayname && a.linknam
在下面的场景中,我有一个 bool 值。根据结果,我调用完全相同的函数,唯一的区别是参数的数量。 var myBoolean = ... if (myBoolean) { retrieve
我是一名研究 C++ 的 C 开发人员: 我是否正确理解如果我抛出异常然后堆栈将展开直到找到第一个异常处理程序?是否可以在不展开的情况下在任何 throw 上打开调试器(即不离开声明它的范围或任何更高
在修复庞大代码库中的错误时,我观察到一个奇怪的情况,其中引用的动态类型从原始 Derived 类型更改为 Base 类型!我提供了最少的代码来解释问题: struct Base { // some
我正在尝试用 C# 扩展给定的代码,但由于缺乏编程经验,我有点陷入困境。 使用 Visual Studio 社区,我尝试通过控制台读出 CPU 核心温度。该代码使用开关/外壳来查找传感器的特定名称(即
这可能是一个哲学问题。 假设您正在向页面发出 AJAX 请求(这是使用 Prototype): new Ajax.Request('target.asp', { method:"post", pa
我有以下 HTML 代码,我无法在所有浏览器中正常工作: 我试图在移动到
我对 Swift 很陌生。我如何从 addPin 函数中检索注释并能够在我的 addLocation 操作 (buttonPressed) 中使用它。我正在尝试使用压力触摸在 map 上添加图钉,在两
我设置了一个详细 View ,我是否有几个 Nib 文件根据在 Root View Controller 的表中选择的项目来加载。 我发现,对于 Nibs 的类,永远不会调用 viewDidUnloa
我需要动态访问 json 文件并使用以下代码。在本例中,“bpicsel”和“temp”是变量。最终结果类似于“data[0].extit1” var title="data["+bpicsel+"]
我需要使用第三方 WCF 服务。我已经在我的证书存储中配置了所需的证书,但是在调用 WCF 服务时出现以下异常。 向 https://XXXX.com/AHSharedServices/Custome
在几个 SO 答案(1、2)中,建议如果存在冲突则不应触发 INSERT 触发器,ON CONFLICT DO NOTHING 在触发语句中。也许我理解错了,但在我的实验中似乎并非如此。 这是我的 S
如果进行修改,则会给出org.hibernate.NonUniqueObjectException。在我的 BidderBO 类(class)中 @Override @Transactional(pr
我使用 indexOf() 方法来精细地查找数组中的对象。 直到此刻我查了一些资料,发现代码应该无法正常工作。 我在reducer中尝试了上面的代码,它成功了 let tmp = state.find
假设我有以下表格: CREATE TABLE Game ( GameID INT UNSIGNED NOT NULL, GameType TINYINT UNSIGNED NOT NU
代码: Alamofire.request(URL(string: imageUrl)!).downloadProgress(closure: { (progress) in
我是一名优秀的程序员,十分优秀!