macOS - 尝试在 NSTextField 上使用自定义 NSFormatter 失败得很惨
macOS - Trying to use a custom NSFormatter on a NSTextField fails miserably
我正在尝试将 NSFormatter
对象添加到 NSTextField
,这样我就可以验证文本字段是否只包含字母数字字符串。
所以我这样做:
- 我创建了一个新的
Swift
macOS 应用程序。
- 我在视图控制器中添加了一个
NSTextField
- 我将自定义
Formatter
添加到视图控制器
- 我使用界面生成器将文本字段的格式化程序出口连接到 Formatter 对象。
我创建这个 class 并分配给 Formatter 对象。
FormatterTextNumbers.h
#import <Foundation/Foundation.h>
@import AppKit;
NS_ASSUME_NONNULL_BEGIN
@interface FormatterTextNumbers : NSFormatter
@end
NS_ASSUME_NONNULL_END
FormatterTextNumbers.m
#import "FormatterTextNumbers.h"
@implementation FormatterTextNumbers
- (BOOL)isAlphaNumeric:(NSString *)partialString
{
static NSCharacterSet *nonAlphanumeric = nil;
if (nonAlphanumeric == nil) {
nonAlphanumeric = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'. -"];
nonAlphanumeric = [nonAlphanumeric invertedSet];
}
NSRange range = [partialString rangeOfCharacterFromSet:nonAlphanumeric];
if (range.location != NSNotFound) {
return NO;
} else {
return YES;
}
}
- (BOOL)isPartialStringValid:(NSString *)partialString
newEditingString:(NSString * _Nullable __autoreleasing *)newString
errorDescription:(NSString * _Nullable __autoreleasing *)error {
if ([partialString length] == 0) {
return YES; // The empty string is okay (the user might just be deleting everything and starting over)
} else if ([self isAlphaNumeric:partialString]) {
*newString = partialString;
return YES;
}
NSBeep();
return NO;
}
你问,为什么我的项目用了Swift
,为什么在Objective-C
里有这些class?简单:如果我使用 Swift
创建 Formatter
class 的子 class,Xcode
将不允许我将那个子class 分配给Formatter
对象。我需要创建 NSFormatter
的 Objective-C
subclass。
说的是,当我 运行 项目时,文本字段消失了,我收到了这条消息,不管这是什么意思:
Failure1[3071:136161] Failed to set (contentViewController) user defined inspected property on (NSWindow): *** -stringForObjectValue: only defined for abstract class. Define -[FormatterTextNumbers stringForObjectValue:]!
我删除了文本字段和 Formatter 对象与应用程序之间的连接 运行 没问题。
您必须定义该方法
来自 NSFormatter
的 Apple 文档(实际上是半抽象的)
Summary
The default implementation of this method raises an exception.
Declaration
- (NSString *)stringForObjectValue:(id)obj;
实际上
也是一样
- (BOOL)getObjectValue:(out id _Nullable * _Nullable)obj forString:(NSString *)string errorDescription:(out NSString * _Nullable * _Nullable)error;
我正在尝试将 NSFormatter
对象添加到 NSTextField
,这样我就可以验证文本字段是否只包含字母数字字符串。
所以我这样做:
- 我创建了一个新的
Swift
macOS 应用程序。 - 我在视图控制器中添加了一个
NSTextField
- 我将自定义
Formatter
添加到视图控制器 - 我使用界面生成器将文本字段的格式化程序出口连接到 Formatter 对象。
我创建这个 class 并分配给 Formatter 对象。
FormatterTextNumbers.h
#import <Foundation/Foundation.h>
@import AppKit;
NS_ASSUME_NONNULL_BEGIN
@interface FormatterTextNumbers : NSFormatter
@end
NS_ASSUME_NONNULL_END
FormatterTextNumbers.m
#import "FormatterTextNumbers.h"
@implementation FormatterTextNumbers
- (BOOL)isAlphaNumeric:(NSString *)partialString
{
static NSCharacterSet *nonAlphanumeric = nil;
if (nonAlphanumeric == nil) {
nonAlphanumeric = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'. -"];
nonAlphanumeric = [nonAlphanumeric invertedSet];
}
NSRange range = [partialString rangeOfCharacterFromSet:nonAlphanumeric];
if (range.location != NSNotFound) {
return NO;
} else {
return YES;
}
}
- (BOOL)isPartialStringValid:(NSString *)partialString
newEditingString:(NSString * _Nullable __autoreleasing *)newString
errorDescription:(NSString * _Nullable __autoreleasing *)error {
if ([partialString length] == 0) {
return YES; // The empty string is okay (the user might just be deleting everything and starting over)
} else if ([self isAlphaNumeric:partialString]) {
*newString = partialString;
return YES;
}
NSBeep();
return NO;
}
你问,为什么我的项目用了Swift
,为什么在Objective-C
里有这些class?简单:如果我使用 Swift
创建 Formatter
class 的子 class,Xcode
将不允许我将那个子class 分配给Formatter
对象。我需要创建 NSFormatter
的 Objective-C
subclass。
说的是,当我 运行 项目时,文本字段消失了,我收到了这条消息,不管这是什么意思:
Failure1[3071:136161] Failed to set (contentViewController) user defined inspected property on (NSWindow): *** -stringForObjectValue: only defined for abstract class. Define -[FormatterTextNumbers stringForObjectValue:]!
我删除了文本字段和 Formatter 对象与应用程序之间的连接 运行 没问题。
您必须定义该方法
来自 NSFormatter
的 Apple 文档(实际上是半抽象的)
Summary The default implementation of this method raises an exception. Declaration - (NSString *)stringForObjectValue:(id)obj;
实际上
也是一样- (BOOL)getObjectValue:(out id _Nullable * _Nullable)obj forString:(NSString *)string errorDescription:(out NSString * _Nullable * _Nullable)error;