Objective c 在活动UITextField之外的触摸上调用函数
当用户触摸具有键盘焦点的UITextField外部时,如何调用自定义函数 我的目标是调用函数进行textfield验证 我试过这个:Objective c 在活动UITextField之外的触摸上调用函数,objective-c,ios,focus,uitextfield,Objective C,Ios,Focus,Uitextfield,当用户触摸具有键盘焦点的UITextField外部时,如何调用自定义函数 我的目标是调用函数进行textfield验证 我试过这个: // Dismiss Keyboard - (void)touchesEnded: (NSSet *)touches withEvent: (UIEvent *)event { for (UIView* view in self.view.subviews) { if ([view isKindOfClass:[UITextField c
// Dismiss Keyboard
- (void)touchesEnded: (NSSet *)touches withEvent: (UIEvent *)event {
for (UIView* view in self.view.subviews) {
if ([view isKindOfClass:[UITextField class]])
{
[view resignFirstResponder];
[self validationForNoOfPassengers];
}
}
}
validationForNoOfPassengers
是我检查验证的方法。这里的问题是,当我点击其他UI控件时,它不会调用上述方法。仅当触摸屏幕外部时(但不在uicontrol上)调用上述方法。有任何指导吗?将视图控制器(或其他对象)设置为文本字段的代理。在-textfieldEndediting:
或-textfieldEndediting:
中执行验证,将视图控制器(或某些其他对象)设置为文本字段的委托。在-textfieldEndediting:
或-textfieldEndediting:
中执行验证,将委托设置到文本字段并执行
方法(在符合的类中)并调用
你在其中的作用:
void
do_something(void)
{
return;
}
/* ... */
- (void)textFieldDidEndEditing:(UITextField *)textField
{
do_something();
}
将委托设置到文本字段并实现 方法(在符合的类中)并调用 你在其中的作用:
void
do_something(void)
{
return;
}
/* ... */
- (void)textFieldDidEndEditing:(UITextField *)textField
{
do_something();
}
尝试覆盖resignFirstResponder并在那里执行验证 尝试覆盖resignFirstResponder并在那里执行验证 编辑 为更好的,通用的解决方案,您可以投入到任何项目 原始答案 其他答案建议在文本字段代理的
textfield shouldenediting:
或textfielddendediting:
方法中进行验证。正如您所发现的,当您触摸控件时,您的文本字段不会将这些消息发送给其代理
它不会发送这些消息,因为它没有结束编辑。当您触摸另一个非文本控件时,文本字段仍然是第一响应者(键盘焦点)
我不知道您是否只有一个或两个文本字段进行了验证,或者有很多文本字段进行了验证。我不知道您是否只有一个或两个非文本控件,或者有很多非文本控件。你的最佳解决方案实际上取决于你拥有什么
你真正想做的是,在每次新触摸时,检查是否有第一响应者,如果有,新触摸是否在第一响应者之外。如果是,则将辞职第一响应者
发送到当前第一响应者(这将使其将文本字段shouldenediting:
发送到其代表),并且仅当辞职第一响应者
返回YES时才继续
如果只有一个文本字段,则可以将顶级视图设置为UIView
的子类,并覆盖hitTest:withEvent:
方法,如下所示:
MyView.h
事实证明,hitTest:withEvent:
实际上在每次触摸时被调用数次(在我的测试中是三次)。因此,如果验证失败,您不仅希望在textfield shouldendediting:
中显示警报,还需要跟踪警报是否已出现在屏幕上。否则,您将看到警报反复弹出
如果您有多个文本字段,上述方法将变得丑陋。您必须检查每一个,看看它是否是当前的第一响应者,而不是触摸视图。如果您可以向系统询问当前的第一响应者,这会容易得多
有一种方法可以返回当前的第一响应者:您可以将第一响应者
发送到[[UIApplication sharedApplication]keyWindow]
以获取当前的第一响应者(如果没有第一响应者,则为null)不幸的是,firstResponder
消息是一个公共API。如果您使用它,则可能不允许您进入应用商店
如果您决定使用它,下面是您在MyView.m中输入的内容:
MyView.m(修订版)
编辑
为更好的,通用的解决方案,您可以投入到任何项目
原始答案
其他答案建议在文本字段代理的textfield shouldenediting:
或textfielddendediting:
方法中进行验证。正如您所发现的,当您触摸控件时,您的文本字段不会将这些消息发送给其代理
它不会发送这些消息,因为它没有结束编辑。当您触摸另一个非文本控件时,文本字段仍然是第一响应者(键盘焦点)
我不知道您是否只有一个或两个文本字段进行了验证,或者有很多文本字段进行了验证。我不知道您是否只有一个或两个非文本控件,或者有很多非文本控件。你的最佳解决方案实际上取决于你拥有什么
你真正想做的是,在每次新触摸时,检查是否有第一响应者,如果有,新触摸是否在第一响应者之外。如果是,则将辞职第一响应者
发送到当前第一响应者(这将使其将文本字段shouldenediting:
发送到其代表),并且仅当辞职第一响应者
返回YES时才继续
如果只有一个文本字段,则可以将顶级视图设置为UIView
的子类,并覆盖hitTest:withEvent:
方法,如下所示:
MyView.h
事实证明,hitTest:withEvent:
实际上在每次触摸时被调用数次(在我的测试中是三次)。因此,如果验证失败,您不仅希望在textfield shouldendediting:
中显示警报,还需要跟踪警报是否已出现在屏幕上。否则,您将看到警报反复弹出
如果您有多个文本字段,上述方法将变得丑陋。您必须检查每一个,看看它是否是当前的第一响应者,而不是触摸视图。如果您可以向系统询问当前的第一响应者,这会容易得多
有一个方法将返回当前的第一个res
#import "MyView.h"
@implementation MyView
@synthesize textField;
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *hitView = [super hitTest:point withEvent:event];
return (hitView != self.textField
&& self.textField.isFirstResponder
&& ![self.textField resignFirstResponder])
? nil : hitView;
}
@end
#import "MyView.h"
@protocol MyViewFirstResponderProtocol
// Have to declare the message so the compiler will allow it.
- (UIResponder *)firstResponder;
@end
@implementation MyView
@synthesize textField;
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
NSLog(@"hitTest for event %@", event);
UIView *hitView = [super hitTest:point withEvent:event];
UIResponder *firstResponder = [(id)self.window firstResponder];
return (firstResponder
&& hitView != firstResponder
&& ![firstResponder resignFirstResponder])
? nil : hitView;
}
@end