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

时间:2014-06-19 22:36:19

标签: ios objective-c cocoa-touch uitextfield

这是我遇到过的最奇怪的事情,问题在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,我仍然会收到冻结。这似乎与设置代表有关?为什么?是否与从initWithCoder设置为self有关?如果是这样,为什么它只是发生在UITextField中,而我的其他自定义类都没有像我在UIScrollView子类中那样将委托设置为self?

1 个答案:

答案 0 :(得分:3)

好吧,进行了一些搜索,但也许这个答案可以帮助任何人试图解决它。

  

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