Mac开发如何处理键盘事件

Mac上输入与手机输入的不同是,Mac需要处理更多的键盘交互,因为Mac上的键盘输入会有多种快捷键组合。

代理方法处理

NSTextField

#pragma mark - NSTextFieldDelegate
- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector
{
    if ([NSStringFromSelector(commandSelector) isEqualToString:@"insertNewline:"]) {
        
        if (([NSApplication sharedApplication].currentEvent.modifierFlags & NSEventModifierFlagShift) != 0) {
            NSLog(@"Shift-Enter detected.");
            [textView insertNewlineIgnoringFieldEditor:self];
            return YES;
        }else {
            NSLog(@"Enter detected.");
        }
    }
    return NO;
}

NSTextView

#pragma mark - NSTextViewDelegate
- (BOOL)textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector
{
    //insertTab:   -键入tab
    //insertNewline:   -键入回车
    //deleteBackward
    
    if ([NSStringFromSelector(commandSelector) isEqualToString:@"insertNewline:"]) {
        
        if (([NSApplication sharedApplication].currentEvent.modifierFlags & NSEventModifierFlagShift) != 0) {
            NSLog(@"Shift-Enter detected.");
            [textView insertNewlineIgnoringFieldEditor:self];
            return YES;
        }else {
            NSLog(@"Enter detected.");
            return YES;
        }
    }
    return NO;
}

通过监听键盘事件处理

[NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskKeyDown handler:^NSEvent * _Nullable(NSEvent * _Nonnull aEvent) {
        [self keyDown:aEvent];
        return aEvent;
    }];
    

然后重写keyDown方法

- (void)keyDown:(NSEvent *)event{
    NSLog(@"%@",event.characters);
    if ([event.characters isEqualToString:@"\r"]) {
        NSLog(@"Enter detected.");
    } else {
        
    }
}

补充 - 格式化键盘输入

OttoCustomFormatter一般用来处理纯数字输入以及密码输入

使用方法

self.inputTF.formatter = [[OttoCustomFormatter alloc] init];

代码实现

OttoCustomFormatter.h

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

typedef enum : NSUInteger {
    OttoCustomFormatterTypeNumber,//纯数字
    OttoCustomFormatterTypePassword,//密码
} OttoCustomFormatterType;

@interface OttoCustomFormatter : NSFormatter

/**
 *  可输入的最大长度 默认为8
 */
@property (nonatomic,assign) NSInteger maxLength;

/**
 *  格式化类型  默认为纯数字类型
 */
@property (nonatomic,assign) OttoCustomFormatterType formatterType;

@end

NS_ASSUME_NONNULL_END

OttoCustomFormatter.m

#import "OttoCustomFormatter.h"

@implementation OttoCustomFormatter

- (instancetype)init{
    self = [super init];
    if (self) {
        self.maxLength = 8;
        self.formatterType = OttoCustomFormatterTypeNumber;
    }
    return self;
}

- (NSString *)stringForObjectValue:(id)obj{
    return (NSString *)obj;
}

- (BOOL)getObjectValue:(out id  _Nullable __autoreleasing *)obj forString:(NSString *)string errorDescription:(out NSString * _Nullable __autoreleasing *)error{
    *obj = string;
    return YES;
}

- (BOOL)isPartialStringValid:(NSString * _Nonnull __autoreleasing *)partialStringPtr proposedSelectedRange:(NSRangePointer)proposedSelRangePtr originalString:(NSString *)origString originalSelectedRange:(NSRange)origSelRange errorDescription:(NSString * _Nullable __autoreleasing *)error{
    if([*partialStringPtr length] == 0)
    {
        return YES;
    }
    if([*partialStringPtr length] > self.maxLength)
    {
        return NO;
    }
    NSRange passwordRange;
    NSString *strLetterDigital;
    if (self.formatterType == OttoCustomFormatterTypeNumber) {
        strLetterDigital = @"1234567890";
    } else if (self.formatterType == OttoCustomFormatterTypePassword) {
        strLetterDigital = @"1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
    }
    NSString *strPassword;
    //使用characterSetWithCharactersInString初始化字符集
    NSCharacterSet *charactersetDigitAndLetter =[NSCharacterSet characterSetWithCharactersInString:strLetterDigital];
    charactersetDigitAndLetter = [charactersetDigitAndLetter invertedSet];
    passwordRange =NSMakeRange(origSelRange.location,
                                proposedSelRangePtr->location
                                - origSelRange.location);
    strPassword= [*partialStringPtr substringWithRange: passwordRange];
    if([strPassword rangeOfCharacterFromSet: charactersetDigitAndLetter
                                       options:NSLiteralSearch].location!=NSNotFound)
    {
        *error =@"Illegal input";
        return(NO);
    }else
    {
        *error =nil;
        return(YES);
    }
}

@end
posted @ 2019-12-23 14:26  大不不  阅读(1110)  评论(0编辑  收藏  举报