类似于这个问题:iPad: Detecting External Keyboard ,我正在开发一个 iPad 应用程序,它使用带有自定义 inputAccessoryView 的文本字段来为虚拟键盘提供额外的功能。
但是,如果硬件键盘(例如蓝牙键盘)连接到设备,则软件键盘不会按预期显示,但出于某种原因,inputAccessoryView 仍然可见 在屏幕底部。此外,这似乎会导致触发 UIKeyboardDidShowNotification(因此向上移动我的 View 以避免被实际上不存在的键盘遮挡),即使使用硬件键盘进行输入也是如此。
我找到了几种检测硬件键盘是否已连接的解决方案,但它们都在收到 UIKeyboardDidShowNotification 后检查状态,此时 inputAccessoryView 已经可见(例如 How can I detect if an external keyboard is present on an iPad? )。
如果没有连接硬件键盘,我正在寻找一种只显示 inputAccessoryView 的方法。因此,我需要知道是否在 触发 UIKeyboardDidShowNotification 之前连接了硬件键盘。
此处提供的公认解决方案 How can I detect if an external keyboard is present on an iPad?对我来说没有选择,因为他们使用私有(private) API,这可能会导致我的应用被拒绝。
最佳答案
这只是@arlomedia 回答的增强版。我所做的是监视 willShow 和 didShow。
我用来将 TextView 移动到适当位置的 willShow,以便它以与键盘相同的速度移动。
我使用的 didShow 使用上述技术检查键盘的外观尺寸并相应地隐藏/显示 accessoryInputView。
重要的,我还将该 View 设置为默认隐藏,并且当收到 willHide 事件时,它会再次隐藏。
- (void) addKeyboardObserver {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardHidden:) name:UIKeyboardWillHideNotification object:nil];
}
- (void) removeKeyboardObserver {
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
- (void)keyboardWillShow:(NSNotification*)notification {
CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
// If we're on iOS7 or earlier and landscape then the height is in the
// width.
//
if ((IS_LANDSCAPE == YES) && (IS_IOS8_OR_LATER == NO)) {
keyboardSize.height = keyboardSize.width;
}
NSNumber *rate = notification.userInfo[UIKeyboardAnimationDurationUserInfoKey];
CGRect textFieldFrame = self.textField.frame;
textFieldFrame.origin.y = ([Util screenHeight] - keyboardSize.height) - textFieldFrame.size.height - [Util scaledHeight:10.0];
// Move the text field into place.
//
[UIView animateWithDuration:rate.floatValue animations:^{
self.answerTextField.frame = textFieldFrame;
}];
keyboardShown = YES;
}
- (void)keyboardDidShow:(NSNotification*)notification {
CGRect keyboardBeginFrame = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
CGRect keyboardEndFrame = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGSize keyboardSize = keyboardBeginFrame.size;
// If we're on iOS7 or earlier and landscape then the height is in the
// width.
//
if ((IS_LANDSCAPE == YES) && (IS_IOS8_OR_LATER == NO)) {
keyboardSize.height = ABS(keyboardBeginFrame.origin.x - keyboardEndFrame.origin.x); // the keyboard will move by an amount equal to its height when it appears; ABS is needed for upside-down orientations
} else {
keyboardSize.height = ABS(keyboardBeginFrame.origin.y - keyboardEndFrame.origin.y); // the keyboard will move by an amount equal to its height when it appears; ABS is needed for upside-down orientations
}
NSNumber *rate = notification.userInfo[UIKeyboardAnimationDurationUserInfoKey];
[UIView animateWithDuration:rate.floatValue animations:^{
if (keyboardSize.height <= self.accessoryBar.frame.size.height) {
self.textField.inputAccessoryView.hidden = YES;
self.answerTextField.inputAccessoryView.userInteractionEnabled = NO;
} else {
self.textField.inputAccessoryView.hidden = NO;
self.answerTextField.inputAccessoryView.userInteractionEnabled = YES;
}
}];
keyboardShown = YES;
}
- (void)keyboardHidden:(NSNotification*)notification {
NSNumber *rate = notification.userInfo[UIKeyboardAnimationDurationUserInfoKey];
// Remove/hide the accessory view so that next time the text field gets focus, if a hardware
// keyboard is used, the accessory bar is not shown.
//
[UIView animateWithDuration:rate.floatValue animations:^{
self.textField.inputAccessoryView.hidden = YES;
self.answerTextField.inputAccessoryView.userInteractionEnabled = NO;
}];
keyboardShown = NO;
}
注意 编辑以添加对 userInteractionEnabled 的更改,以便隐藏的 accessoryView 不会消耗水龙头。
关于ios - 如果连接了硬件键盘,则隐藏 inputAccessoryView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27830857/
我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat
我正在尝试在Ruby中制作一个cli应用程序,它接受一个给定的数组,然后将其显示为一个列表,我可以使用箭头键浏览它。我觉得我已经在Ruby中看到一个库已经这样做了,但我记不起它的名字了。我正在尝试对soundcloud2000中的代码进行逆向工程做类似的事情,但他的代码与SoundcloudAPI的使用紧密耦合。我知道cursesgem,我正在考虑更抽象的东西。广告有没有人见过可以做到这一点的库或一些概念证明的Ruby代码可以做到这一点? 最佳答案 我不知道这是否是您正在寻找的,但也许您可以使用我的想法。由于我没有关于您要完成的工作
我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
如果我使用ruby版本2.5.1和Rails版本2.3.18会怎样?我有基于rails2.3.18和ruby1.9.2p320构建的rails应用程序,我只想升级ruby的版本,而不是rails,这可能吗?我必须面对哪些挑战? 最佳答案 GitHub维护apublicfork它有针对旧Rails版本的分支,有各种变化,它们一直在运行。有一段时间,他们在较新的Ruby版本上运行较旧的Rails版本,而不是最初支持的版本,因此您可能会发现一些关于需要向后移植的有用提示。不过,他们现在已经有几年没有使用2.3了,所以充其量只能让更
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里