Mac开发基础11-NSTextField(一)

NSTextField 是 macOS 应用中常用的 UI 元素之一,它用于显示和输入文本。NSTextField 提供了丰富的 API 来定制和处理用户输入。

常见 API 和技巧

1. 初始化 NSTextField

程序化创建

Objective-C
NSTextField *textField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 22)];
[textField setStringValue:@"Initial Text"];
Swift
let textField = NSTextField(frame: NSMakeRect(0, 0, 200, 22))
textField.stringValue = "Initial Text"

Interface Builder(IB)创建

在 IB 中拖动一个 NSTextField 到界面。然后在代码中通过 IBOutlet 连接。

Objective-C
@property (weak) IBOutlet NSTextField *textField;
Swift
@IBOutlet weak var textField: NSTextField!

2. 设置和获取文本值

设置文本

Objective-C
[self.textField setStringValue:@"New Text"];
Swift
self.textField.stringValue = "New Text"

获取文本

Objective-C
NSString *currentText = [self.textField stringValue];
Swift
let currentText = self.textField.stringValue

3. 占位符文字

占位符文字提供了提示信息,当文本框为空时显示。

设置占位符文字

Objective-C
[self.textField setPlaceholderString:@"Enter your text here"];
Swift
self.textField.placeholderString = "Enter your text here"

4. 文本对齐和样式

设置文本对齐

Objective-C
[self.textField setAlignment:NSTextAlignmentCenter];
Swift
self.textField.alignment = .center

设置文本颜色和字体

Objective-C
[self.textField setTextColor:[NSColor redColor]];
[self.textField setFont:[NSFont fontWithName:@"Helvetica" size:14]];
Swift
self.textField.textColor = NSColor.red
self.textField.font = NSFont(name: "Helvetica", size: 14)

5. 禁用编辑和选择

有时你可能希望文本框只用于显示,而不是让用户编辑。

禁用编辑

Objective-C
[self.textField setEditable:NO];
Swift
self.textField.isEditable = false

禁用选择

Objective-C
[self.textField setSelectable:NO];
Swift
self.textField.isSelectable = false

6. 处理用户输入

通过委托处理输入(NSTextFieldDelegate

通过实现 NSTextFieldDelegate 的方法,可以处理用户输入时的各种事件。

Objective-C
@interface ViewController : NSViewController <NSTextFieldDelegate>
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.textField.delegate = self;
}

- (void)controlTextDidChange:(NSNotification *)notification {
    NSTextField *textField = notification.object;
    NSLog(@"New value: %@", textField.stringValue);
}

@end
Swift
class ViewController: NSViewController, NSTextFieldDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        textField.delegate = self
    }

    func controlTextDidChange(_ obj: Notification) {
        if let textField = obj.object as? NSTextField {
            print("New value: \(textField.stringValue)")
        }
    }
}

7. 回车键处理(自动完成)

可以捕捉回车键事件并处理它,例如自动完成输入。

回车键处理

Objective-C
- (void)controlTextDidEndEditing:(NSNotification *)obj {
    NSNumber *movement = obj.userInfo[@"NSTextMovement"];
    if (movement.integerValue == NSReturnTextMovement) {
        NSLog(@"Return key pressed");
    }
}
Swift
func controlTextDidEndEditing(_ obj: Notification) {
    if let movement = (obj.userInfo?["NSTextMovement"] as? NSNumber)?.intValue,
       movement == NSReturnTextMovement {
        print("Return key pressed")
    }
}

8. 自定义背景和边框

可以通过属性定制 NSTextField 的外观。

自定义背景颜色和边框颜色

Objective-C
[self.textField setDrawsBackground:YES];
[self.textField setBackgroundColor:[NSColor yellowColor]];
[self.textField setBordered:YES];
[self.textField setBezeled:YES];
[self.textField setBezelStyle:NSTextFieldRoundedBezel];
Swift
self.textField.drawsBackground = true
self.textField.backgroundColor = .yellow
self.textField.isBordered = true
self.textField.isBezeled = true
self.textField.bezelStyle = .roundedBezel

9. 格式化输入

通过配置 NSFormatter,可以限制并格式化用户输入。

使用 NSNumberFormatter 格式化数值输入

Objective-C
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterDecimalStyle;
[self.textField setFormatter:formatter];
Swift
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
self.textField.formatter = formatter

10. 失去焦点/达到焦点事件处理

可以捕捉文本框的焦点事件,以处理特定的需求。

处理焦点事件

Objective-C
- (BOOL)control:(NSControl *)control textShouldBeginEditing:(NSText *)fieldEditor {
    NSLog(@"Text field gained focus");
    return YES;
}

- (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor {
    NSLog(@"Text field lost focus");
    return YES;
}
Swift
func control(_ control: NSControl, textShouldBeginEditing fieldEditor: NSText) -> Bool {
    print("Text field gained focus")
    return true
}

func control(_ control: NSControl, textShouldEndEditing fieldEditor: NSText) -> Bool {
    print("Text field lost focus")
    return true
}

深入探讨 NSTextField

1. 响应链机制

NSTextField 是响应链的一部分,当用户在文本框中进行操作时,事件会沿着响应链传递,直到找到可以处理该事件的对象。借助响应链机制,NSTextField 可以委托事件处理给其委托对象,比如 controlTextDidChange:

2. KVO 和 KVC

NSTextField 可以使用键值观察(KVO)来观察其属性变化。比如观察 stringValue 属性的变化:

KVO 观察示例

Objective-C
[self.textField addObserver:self forKeyPath:@"stringValue" options:NSKeyValueObservingOptionNew context:nil];

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    if ([keyPath isEqualToString:@"stringValue"]) {
        NSLog(@"New value: %@", change[NSKeyValueChangeNewKey]);
    }
}

- (void)dealloc {
    [self.textField removeObserver:self forKeyPath:@"stringValue"];
}
Swift
textField.addObserver(self, forKeyPath: "stringValue", options: .new, context: nil)

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if keyPath == "stringValue" {
        print("New value: \(change?[.newKey] ?? "")")
    }
}

deinit {
    textField.removeObserver(self, forKeyPath: "stringValue")
}

3. 关联属性和用户属性

可以为 NSTextField 添加额外的元数据:

Objective-C

objc_setAssociatedObject(self.textField, @"key", @"value", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
NSString *value = objc_getAssociatedObject(self.textField, @"key");
NSLog(@"Associated Value: %@", value);

Swift

objc_setAssociatedObject(textField, "key" as NSString, "value", .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
let value = objc_getAssociatedObject(textField, "key" as NSString) as? String
print("Associated Value: \(String(describing: value))")

4. 利用 Core Text 实现高级文本处理

NSTextField 可以与 Core Text 协作,实现更复杂的文本格式化和绘制。

绘制富文本

Objective-C
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:@"Hello, World!"
                                                                 attributes:@{NSForegroundColorAttributeName: [NSColor blueColor],
                                                                              NSFontAttributeName: [NSFont fontWithName:@"Helvetica-Bold" size:16]}];
[textField setAttributedStringValue:attrString];
Swift
let attrString = NSAttributedString(string: "Hello, World!", attributes: [.foregroundColor: NSColor.blue, .font: NSFont(name: "Helvetica-Bold", size: 16)!])
textField.attributedStringValue = attrString

5. 支持动态 Type 和 Accessibility

NSTextField 支持响应 macOS 的动态类型设置和辅助功能(Accessibility),可以为每个用户提供更佳的使用体验。

启用辅助功能

默认情况下,NSTextField 就支持辅助功能。如果有特定需求,可以通过 NSAccessibility 协议进一步自定义:

Objective-C
// Implement NSAccessibility protocol methods
- (NSArray *)accessibilityActionNames {
    return @[NSAccessibilityPressAction];
}

- (void)accessibilityPerformPress {
    NSLog(@"Accessibility action performed");
}
Swift
// Implement NSAccessibility protocol methods
override func accessibilityActionNames() -> [NSAccessibility.ActionName] {
    return [.press]
}

override func accessibilityPerformAction(_ action: NSAccessibility.ActionName) {
    if action == .press {
        print("Accessibility action performed")
    }
}
posted @ 2024-08-06 16:12  Mr.陳  阅读(24)  评论(0编辑  收藏  举报