为了检测Backspace,我覆盖了DeleteBackward
方法(应该适用于iOS5 +)
var input = new BackspaceTextField(RectangleF.Empty);
etc
input.BecomeFirstResponder();
这是代码
public sealed class BackspaceTextField : UITextField
{
public BackspaceTextField(RectangleF frame) : base(frame)
{
}
public override void DeleteBackward ()
{
Console.WriteLine ("DeleteBackward");
}
}
当我按“Backspace”按钮时没有任何反应。我希望应该出现“DeleteBackward”消息
环境:iOS8,xamarin
编辑:0
关于objective-c的类似问题:Detect backspace in UITextField
我已经做了额外的检查。 DeleteBackward
是来自UIKeyInput协议的方法,因此我检查insertText
方法,此方法可以正常工作。
public override void InsertText (string text)
{
base.InsertText(text);
}
我在objective-c上检查了deleteBackward
,它也完美无缺。
您是否有任何想法如何在iOS8中的UITextField中检测退格?
请您澄清为什么没有调用DeleteBackward
方法?
修改:1
我已经向Xamarin的forum提交了同样的问题。看起来像iOS8 + xamarin中的一个错误,因为在iOS 7.1中可以正常工作。
这是一个错误。这是details
答案 0 :(得分:24)
许多人一直在说这是一个错误,但由于这个问题在GM中仍然存在,我开始认为它可能是逻辑上的变化。话虽如此,我为我的应用程序编写了这段代码,并在iOS 7-8上进行了测试。
此代码稍微位于私有API的红线之前,但是使用它时应该没有问题。我的应用程序使用此代码在应用程序商店中。
将以下方法添加到UITextField
子类。
- (BOOL)keyboardInputShouldDelete:(UITextField *)textField {
BOOL shouldDelete = YES;
if ([UITextField instancesRespondToSelector:_cmd]) {
BOOL (*keyboardInputShouldDelete)(id, SEL, UITextField *) = (BOOL (*)(id, SEL, UITextField *))[UITextField instanceMethodForSelector:_cmd];
if (keyboardInputShouldDelete) {
shouldDelete = keyboardInputShouldDelete(self, _cmd, textField);
}
}
BOOL isIos8 = ([[[UIDevice currentDevice] systemVersion] intValue] == 8);
BOOL isLessThanIos8_3 = ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.3f);
if (![textField.text length] && isIos8 && isLessThanIos8_3) {
[self deleteBackward];
}
return shouldDelete;
}
要解释一下,请调用此方法的超级实现,以避免丢失继承的代码。如果没有文本且iOS版本介于8-8.2之间,则打电话给-deleteBackward
。
编辑:2015年1月28日
子类化子类UITextField的-deleteBackward方法也可能有所帮助。这修复了一些有条件的错误。一种是如果你使用自定义键盘。这是该方法的一个例子。
- (void)deleteBackward {
BOOL shouldDismiss = [self.text length] == 0;
[super deleteBackward];
if (shouldDismiss) {
if ([self.delegate respondsToSelector:@selector(textField:shouldChangeCharactersInRange:replacementString:)]) {
[self.delegate textField:self shouldChangeCharactersInRange:NSMakeRange(0, 0) replacementString:@""];
}
}
}
编辑:答案翻译成Xamarin,因为最初的问题是Xamarin问的。
[Preserve]
[Export("keyboardInputShouldDelete:")]
private bool KeyboardInputShouldDelete(UITextField textField)
{
var shouldDelete = true;
if(RespondsToSelector(new Selector("_cmd")))
{
//Call base class
shouldDelete = Messaging.bool_objc_msgSend_IntPtr(Handle, Selector.GetHandle("_cmd"), textField.Handle);
}
//ios8 "bug": always call DeleteBackward even if the field is empty
if(Utils.IsIos8)
{
DeleteBackward();
return false;
}
return shouldDelete;
}
在ios 7.1和8.1上验证
编辑:4/14/15
自iOS 8.3起,此问题已得到修复。 Objective-C代码已更新以反映更改。
编辑:2015年7月24日
正如@nischalhada所评论的那样,存在两次调用文本字段-textField:shouldChangeCharactersInRange:replacementString:
的状态。使用自定义键盘时,iOS&gt; = 8.3存在问题。我的解决方案并不理想,但它完成了工作,我不确定是否还有其他办法。由于对此方法的两次调用都是在同一个运行循环上执行的,因此我们将使用bool来跟踪何时执行代码以及调度async以重置bool。
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
BOOL toReturn = NO;
if (!self.shouldTextFieldPreventChange) {
self.shouldTextFieldPreventChange = YES;
dispatch_async(dispatch_get_main_queue(), ^{
// iOS8.3 custom keyboards might call this method along with internal iOS
// code. Allowing changes on the next run loop helps avoid this issue.
self.shouldTextFieldPreventChange = NO;
});
// do work...
}
return toReturn;
}
答案 1 :(得分:1)
准确地说,这是一个Apple iOS8错误。在Apple的开发者论坛上,已经有几次reported次。遗憾的是,这些错误报告无法公开访问,因此我们所知道的是它仍然会发生在测试版5中。
附注:一般情况下(99%),大多数Xamarin.iOS绑定并非特定于iOS版本(即没有版本检查),因此iOS版本之间的不同行为通常是设计(记录在案)或 Apple bug (就像这个)。