NSTextField의 문자 수 제한 수행

개요


  • NSTextField 의 입력 문자수에 제한을 걸고 싶다.
  • 이번에는 2 종류를 시험한다. 1개는 NSTextField , 다른 하나는 NSFormatter 의 커스텀 클래스를 만드는 것.

  • GitHub



  • htps : // 기주 b. 코 m / Pom m Dau / 쿠이타 _ te xt fu e ldo th chura c r no mbe r mi t
  • 이번 작성한 샘플은 이쪽으로부터.


  • 방법 1_NSTextField의 사용자 지정 클래스 만들기



    구현



    FirstWindowTextField.m
    #import "FirstWindowTextField.h"
    
    static const NSUInteger kCharLimit = 5; // 文字数制限
    
    @interface FirstWindowTextField() <NSTextFieldDelegate>
    @end
    
    @implementation FirstWindowTextField
    
    - (void)drawRect:(NSRect)dirtyRect {
        [super drawRect:dirtyRect];
    
        // Drawing code here.
    }
    
    - (id) initWithCoder:(NSCoder *)decoder
    {
        self = [super initWithCoder:decoder];
        if (self) {
            [self setDelegate: self];
        }
        return self;
    }
    
    // MARK:- NSTextFieldDelegate(実際はNSControl由来) Methods
    - (void)controlTextDidChange:(NSNotification *)aNotification {
        NSString *newString = [self stringValue];
        if ([newString length] > kCharLimit) {
            [self setStringValue:[newString substringToIndex:kCharLimit]];
        }
    }
    
    @end
    
  • NSTextField의 서브 클래스를 작성해, xib측에서 NSTextField의 클래스에 지정.
  • NSTextFieldDelegate(실제로는 NSControl의 Delegate 유래)의 메소드를 사용해, 텍스트가 입력될 때마다 불리는 메소드를 이용해 문자수 제한을 실시한다.
  • 입력 후의 문자수가 제한을 오버하고 있었던 경우, substringToIndex:kCharLimit 그리고 전부터 제한 문자수를 꺼내고 있다.
  • controlTextDidChange:(NSNotification *)aNotification;
    

    방법 2_NSFormatter의 사용자 지정 클래스 만들기



    참고



  • objective c - How to limit NSTextField text length and keep it always upper case? - Stack Overflow
  • 아이디어는 이쪽으로부터.


  • (구) Cocoa의 매일 : NSFormatter
  • NSTextField에 NSFormatter를 적용하는 방법


  • Creating a Custom Formatter
  • Apple 공식 문서


  • isPartialStringValid:newEditingString:errorDescription:
  • Apple 공식 문서


  • 구현(코드)


  • NSFormatter 의 커스텀 클래스, CustomTextFieldFormatter 를 작성한다.

  • //  CustomTextFieldFormatter.m
    //  TextFieldWithCharacterNumberLimit
    
    #import "CustomTextFieldFormatter.h"
    
    @interface CustomTextFieldFormatter ()
    @property NSUInteger charLimit; // 制限文字数
    @end
    
    @implementation CustomTextFieldFormatter
    - (id)init {
        if(self = [super init]){
            [self setCharLimit:3];
        }
        return self;
    }
    
    /**
     @brief 部分文字列が有効かどうか - ユーザがキーを押す際に呼ばれる
     @param partialString 現在セル内にあるテキスト
     @param newString partialStringの変更が必要なときの置換文字列
     @return 部分文字列が有効かどうか
     */
    - (BOOL)isPartialStringValid:(NSString *)partialString
                newEditingString:(NSString **)newString
                errorDescription:(NSString **)error {
        if ((int)[partialString length] > _charLimit) {
            *newString = [partialString substringToIndex:_charLimit];
            return NO;  // newStringでpartialStringを置換
        }
        return YES;
    }
    
    // MARK:- NSFormatter Methods
    // NSFormatterのカスタムクラス作成に必須なメソッド
    
    /**
     @brief セルのオブジェクトを文字列表現に変換(数値→文字列)
     */
    - (NSString *)stringForObjectValue:(id)object {
        return (NSString *)object;
    }
    
    /**
     @brief 文字列をセルに関連付けられたオブジェクトに変換(文字列→数値)
     */
    - (BOOL)getObjectValue:(id *)object
                 forString:(NSString *)string
          errorDescription:(NSString **)error {
        *object = string;
        return YES;
    }
    @end
    
  • 다음은 사용자가 키를 누를 때 호출되는 메소드로 부분 문자열이 유효한지 여부를 반환합니다.
  • 하고 있는 것은 방법 1 과 같이, 제한 문자수보다 많은 경우, newString 에 제한 문자수의 캐릭터 라인을 대입하고 있다.
  • /**
     @brief 部分文字列が有効かどうか - ユーザがキーを押す際に呼ばれる
     @param partialString 現在セル内にあるテキスト
     @param newString partialStringの変更が必要なときの置換文字列
     @return 部分文字列が有効かどうか
     */
    - (BOOL)isPartialStringValid:(NSString *)partialString
                newEditingString:(NSString **)newString
                errorDescription:(NSString **)error {
        if ((int)[partialString length] > _charLimit) {
            *newString = [partialString substringToIndex:_charLimit];
            return NO;  // newStringでpartialStringを置換
        }
        return YES;
    }
    
    
  • 아래는 NSFormatter 의 커스텀 클래스를 작성할 때 override가 필요한 메소드.
  • // MARK:- NSFormatter Methods
    // NSFormatterのカスタムクラス作成に必須なメソッド
    /**
     @brief セルのオブジェクトを文字列表現に変換(数値→文字列)
     */
    - (NSString *)stringForObjectValue:(id)object {
        return (NSString *)object;
    }
    
    /**
     @brief 文字列をセルに関連付けられたオブジェクトに変換(文字列→数値)
     */
    - (BOOL)getObjectValue:(id *)object
                 forString:(NSString *)string
          errorDescription:(NSString **)error {
        *object = string;
        return YES;
    }
    

    구현 (xib 측)


  • 오브젝트를 삽입해, 클래스를 CustomTextFieldFormatter 로 한다.


  • 포맷터에 대한 사용자 정의 설정



  • 도전


  • 이하는 통상 동작은 하지만, 문자 제한을 넘는 붙여 넣을 때에 문자가 전혀 들어가지 않는 것이 문제.
  • e.g. 3문자 제한일 때, "아"+ "이에오"→ "아"그대로.
  • "아이"가 되길 바란다.

  • 이것을 사용해 잘 하는 방법은 있을까…
  • isPartialStringValid:proposedSelectedRange:originalString:originalSelectedRange:errorDescription:
  • /**
     @brief 無効な文字を入力しないようにする
     @param partialStringPtr 検証する新しい文字列
     @param proposedSelRangePtr 文字列が受け入れられるか置き換えられる場合に使用される選択範囲。
     @param origString 変更が提案される前の元の文字列。
     @param origSelRange 変更が行われる選択範囲。
     */
    - (BOOL)isPartialStringValid:(NSString **)partialStringPtr
           proposedSelectedRange:(NSRangePointer)proposedSelRangePtr
                  originalString:(NSString *)origString
           originalSelectedRange:(NSRange)origSelRange
                errorDescription:(NSString **)error {
        int size = (int)[*partialStringPtr length];
        if (size > _charLimit) {
            return NO;
        }
        return YES;
    }
    

    좋은 웹페이지 즐겨찾기