打开表情符号键盘时自定义 UITextField 冻结应用程序?

Posted

技术标签:

【中文标题】打开表情符号键盘时自定义 UITextField 冻结应用程序?【英文标题】:Custom UITextField Freezes App When Opening Emoji Keyboard? 【发布时间】:2014-06-19 22:36:18 【问题描述】:

这是我遇到过的最奇怪的事情,而且问题在 iPhone 4 和 iPhone 5s 上都是一致的......

我创建了一个 UITextField 的子类来添加一些自定义功能,并将 UITextField 的自定义类设置为我在故事板中的自定义类。

太好了,一切都很好 - 但是.. 每当我点击打开字段时,我都可以正常输入 - 只要我点击键盘的表情符号地球部分,应用程序就会立即锁定。它没有崩溃,我只是无能为力,打字指示灯停止闪烁,应用程序无限挂起..

太奇怪了。

这是我创建的自定义类。

标题

#import <UIKit/UIKit.h>

@interface GenericTextField : UITextField <UITextFieldDelegate>

@property id nextField;
@property id nextCallbackTarget;
@property SEL nextCallbackSelector;

@end

实施

#import "GenericTextField.h"

@implementation GenericTextField

- (id)initWithCoder:(NSCoder *)aDecoder

    if (self = [super initWithCoder:aDecoder]) 
        [self setup];
    
    return self;


- (void)setup

    self.delegate = self;


- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField

    return YES;


- (BOOL)textFieldShouldReturn:(UITextField *)textField

    if ([self.nextField respondsToSelector:@selector(becomeFirstResponder)]) 
        [self.nextField becomeFirstResponder];
     else 
        [self resignFirstResponder];
        if ([self.nextCallbackTarget respondsToSelector:self.nextCallbackSelector]) 
            #pragma clang diagnostic push
            #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
            [self.nextCallbackTarget performSelector:self.nextCallbackSelector];
            #pragma clang diagnostic pop
        
    

    return NO;


@end

这是另一个有趣的部分。如果我注释掉我将委托设置为 self 的部分,一切正常。但是,如果我注释掉我的自定义委托方法并在 setup 方法中将委托设置为 self,我仍然会冻结。这似乎与设置委托特别相关?为什么?它是否与从 initWithCoder 将其设置为 self 有关?如果是这样,为什么它只发生在 UITextField 中,而我的其他自定义类都没有像我制作的 UIScrollView 子类那样将委托设置为 self?

【问题讨论】:

另外,我的手机在挂起时开始变热。这让我觉得有些东西卡在了一个循环中。仍在搜索... 我相信这是问题所在。 ***.com/questions/1747777/… 在 Xcode 中运行您的应用程序。当它似乎冻结时,给它几秒钟,然后点击调试器中的“暂停”图标。查看调试器左侧的堆栈跟踪。怎么回事? 【参考方案1】:

好的,进行了一些搜索,但也许这个答案会帮助任何试图弄清楚的人。

UITextField 是独一无二的 AFAIK。你通常可以使用一个类作为它自己的 代表没有特别的问题。对于 UITextField 你必须创建 一个实际的委托(当然,它可以调用 作为委托的 UITextField。只是要小心避免保留 循环,即使您使用的是 ARC)。

这导致我尝试在我的植入中更新一些代码,并创建一个共享委托类来以我能想到的最简单的方式处理委托。这是更新后的实现。

希望对你有帮助!

#import "GenericTextField.h"

@interface GenericTextFieldDelegate : NSObject <UITextFieldDelegate>
+ (GenericTextFieldDelegate *)sharedDelegate;
@end

@implementation GenericTextFieldDelegate

+ (GenericTextFieldDelegate *)sharedDelegate

    static GenericTextFieldDelegate *genericTextFieldDelegate;
    @synchronized(self) 
        if (!genericTextFieldDelegate) 
            genericTextFieldDelegate = [[GenericTextFieldDelegate alloc] init];
        
    

    return genericTextFieldDelegate;


- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField

    return YES;


- (BOOL)textFieldShouldReturn:(GenericTextField *)textField

    if ([textField.nextField respondsToSelector:@selector(becomeFirstResponder)]) 
        [textField.nextField becomeFirstResponder];
     else 
        [textField resignFirstResponder];
        if ([textField.nextCallbackTarget respondsToSelector:textField.nextCallbackSelector]) 
            #pragma clang diagnostic push
            #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
            [textField.nextCallbackTarget performSelector:textField.nextCallbackSelector];
            #pragma clang diagnostic pop
        
    

    return NO;


@end

@implementation GenericTextField

- (id)initWithCoder:(NSCoder *)aDecoder

    if (self = [super initWithCoder:aDecoder]) 
        [self setup];
    
    return self;


- (void)setup

    self.delegate = [GenericTextFieldDelegate sharedDelegate];


@end

【讨论】:

感谢发帖;我今天早上遇到了这个确切的问题,甚至不知道从哪里开始。

以上是关于打开表情符号键盘时自定义 UITextField 冻结应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

在 UITextField 与 UIViewRepresentable 和 SwifUI 之间绑定文本时出现问题

android studio 从默认键盘打开表情符号键盘

像我们在 uitextfield 中插入表情符号(unicodes)一样插入图像

React-native:打开表情符号键盘

Ionic / Cordova / Phonegap:有没有办法在iOS和Android上禁用表情符号键盘?

UITextField - 防止用户输入非标准字符(如表情符号)