我有一个UITextField
的子类,它设置了self.delegate = self
。子类用于防止将特殊字符输入UITextField
。起初它工作正常,但在按下几个键之后,CPU峰值达到100%并冻结应用程序。 Xcode中没有崩溃日志,因为应用程序实际上从未崩溃,只是在我停止之前一直保持冻结状态。经过一些研究,我确定问题是将delegate
设置为self
- 显然我应该为delegate
单独UITextField
?我在网上搜索过,但找不到有关如何做到这一点的任何有用信息。
我的AcceptedCharacters子类:
AcceptedCharacters.h
#import <UIKit/UIKit.h>
@interface AcceptedCharacters : UITextField <UITextFieldDelegate>
@end
和
AcceptedCharacters.m
#import "AcceptedCharacters.h"
#define ACCEPTABLE_CHARACTERS @" ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_."
@implementation AcceptedCharacters
- (void)awakeFromNib
{
[super awakeFromNib];
if (self) {
self.delegate = self;
}
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
//NSLog(@"AcceptedCharacters");
// Restrict special characters
NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:ACCEPTABLE_CHARACTERS] invertedSet];
NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
return [string isEqualToString:filtered];
}
@end
我在堆栈溢出时发现的类似问题:
Application freezes after editing custom UITextField
UITextField delegate jumping to 100% CPU usage and crashing upon using keyboard shortcut
Why does UITextField lock up when setting itself to delegate
我已阅读过这些解决方案,但对于初学者而言,它们相当模糊。我非常感谢有人修改我的代码,甚至指向我的教程或文档的方向?提前谢谢。
编辑:
我已在我的ViewControllers
之一上测试了此代码,并且在符合UITextFieldDelegate
协议且文本字段delegates
设置为self
时效果正常(请参阅下面的片段)。
在我的viewDidLoad
方法中:
self.forenameField.delegate = self;
self.surnameField.delegate = self;
self.addLine1Field.delegate = self;
self.addLine2Field.delegate = self;
self.addLine3Field.delegate = self;
self.addLine4Field.delegate = self;
self.addLine5Field.delegate = self;
self.postcodeField.delegate = self;
self.telLandField.delegate = self;
self.telMobField.delegate = self;
self.emailField.delegate = self;
self.dobField.delegate = self;
self.niNumField.delegate = self;
我宁愿创建几个UITextField
的子类,并在特定的文本字段上调用它们,而不是像下面那样有一个混乱的方法。
#define ACCEPTABLE_CHARACTERS @" ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_."
#define NUMBERS_ONLY @"1234567890"
#define CHARACTER_LIMIT 11
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
// Restrict special characters
NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:ACCEPTABLE_CHARACTERS] invertedSet];
NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
// Convert postcode field characters to uppercase
if (textField == self.postcodeField) {
[textField setText:[textField.text stringByReplacingCharactersInRange:range withString:[string uppercaseString]]];
return NO;
}
// Set max character limit on tel fields
if (textField == self.telMobField || textField == self.telLandField) {
NSUInteger newLength = [textField.text length] + [string length] - range.length;
NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:NUMBERS_ONLY] invertedSet];
NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
return (([string isEqualToString:filtered])&&(newLength <= CHARACTER_LIMIT));
}
//return YES;
return [string isEqualToString:filtered];
}
答案 0 :(得分:1)
请改为尝试:
@interface MyTextField : UITextField
- (BOOL)stringIsAcceptable:(NSString *)string inRange:(NSRange)range;
@end
@implementation MyTextField
- (BOOL)stringIsAcceptable:(NSString *)string inRange:(NSRange)range {
NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:ACCEPTABLE_CHARACTERS] invertedSet];
NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
return [string isEqualToString:filtered];
}
@end
@interface PostalCodeTextField : MyTextField
@end
@implementation PostalCodeTextField
- (BOOL)stringIsAcceptable:(NSString *)string inRange:(NSRange)range {
[self setText:[self.text stringByReplacingCharactersInRange:range withString:[string uppercaseString]]];
return NO;
}
@end
.. more subclasses
然后将视图控制器指定为委托并在视图控制器中:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if ([textField isKindOfClass:[MyTextField class]]) {
return [(MyTextField *)textField stringIsAcceptable:string inRange:range];
}
return YES;
}