【Objective-C】UITextFieldのキャレット(カーソル)操作あれこれ
UITextViewには比較的直感的にキャレット位置を取得できるselectedRangeプロパティがありますが、UITextFieldには数値としての位置情報を持たないselectedTextRangeプロパティしかないため、単純に現在位置を取得したり、指定位置に移動させたりするのも一苦労です。
調べたところ、日本語の情報がないようだったのでメモ。
以下は、StackOverflowから拝借したコードを整理したものです。
//キャレット位置セット - (void)selectTextForInput:(UITextField *)input atRange:(NSRange)range { UITextPosition *start = [input positionFromPosition:[input beginningOfDocument] offset:range.location]; UITextPosition *end = [input positionFromPosition:start offset:range.length]; [input setSelectedTextRange:[input textRangeFromPosition:start toPosition:end]]; } //キャレット位置取得 - (NSInteger)getCaretLocationForInput:(UITextField *) input { UITextRange *selRange = input.selectedTextRange; UITextPosition *selStartPos = selRange.start; return [input offsetFromPosition:input.beginningOfDocument toPosition:selStartPos]; }
これをさらにObjective-Cらしく、再利用可能にするためカテゴリ化したものが以下。
UITextField+ControlCaret.h
#import <UIKit/UIKit.h> @interface UITextField (ControlCaret) - (void)selectTextAtRange:(NSRange)range; - (NSInteger)getCaretLocation; @end
UITextField+ControlCaret.m
#import "UITextField+ControlCaret.h" @implementation UITextField (ControlCaret) - (void)selectTextAtRange:(NSRange)range { UITextPosition *start = [self positionFromPosition:[self beginningOfDocument] offset:range.location]; UITextPosition *end = [self positionFromPosition:start offset:range.length]; [self setSelectedTextRange:[self textRangeFromPosition:start toPosition:end]]; } - (NSInteger)getCaretLocation { UITextRange *selRange = self.selectedTextRange; UITextPosition *selStartPos = selRange.start; return [self offsetFromPosition:self.beginningOfDocument toPosition:selStartPos]; } @end
...カテゴリの命名規則ってこんな感じで良いのでしょうか。
よく、「元クラス名+カテゴリ名」と記載されていますが、そのカテゴリ名部分が知りたいんだよ!というね。