1

UITextview からカーソル位置を取得したいのですが、「UITextView でカーソルのピクセル位置を見つける方法」のコードを実装しました。投稿、アルゴリズムはUITextView の Cursor の Pixel-Position のアルゴリズムに基づいています。

私の問題は、キーボードが 2 回目に表示された後、selectedRange.location の値を取得できないことです。これは、常に location の値が 2147483647 であることを示しているため、見つからないことを意味します。これは私の実装です:

-(void)getCursorPosition{
NSRange originalPosition = self.codeTextView.selectedRange;
NSLog(@"original position : %d", self.codeTextView.selectedRange.location);
CGPoint origin = self.codeTextView.frame.origin;
unichar c = ' ';

NSLog(@"location : %d", self.codeTextView.selectedRange.location);
NSLog(@"length : %d", self.codeTextView.selectedRange.length);

if (self.codeTextView.selectedRange.location != [self.codeTextView.text length]) {
    //  NSLog(@"cek 1");
    c = [self.codeTextView.text characterAtIndex:self.codeTextView.selectedRange.location];
    //  NSLog(@"cek 2");        
}

NSLog(@"c : %d", c);

if (c!=32 && c!=10) {
    NSRange delimiter = [self.codeTextView.text rangeOfCharacterFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] 
                                                                options:NSLiteralSearch 
                                                                  range:NSMakeRange(self.codeTextView.selectedRange.location, 
                                                                                    [self.codeTextView.text length] - self.codeTextView.selectedRange.location)];
    if (delimiter.location == NSNotFound) {
        delimiter.location = [self.codeTextView.text length];
    }
    self.codeTextView.selectedRange = delimiter;
    NSLog(@"delimiter length : %d, location : %d", delimiter.length, delimiter.location);
}



int deviationLocation = self.codeTextView.selectedRange.location - originalPosition.location;
NSString *head = [self.codeTextView.text substringToIndex:self.codeTextView.selectedRange.location];
CGSize initialSize = [head sizeWithFont:self.codeTextView.font constrainedToSize:CGSizeMake(self.codeTextView.frame.size.width, 
                                                                                            self.codeTextView.frame.size.height)];
NSUInteger startOfLine = [head length];
BOOL isFirstLine = NO;

NSLog(@"initialize height : %f", initialSize.height);
NSLog(@"code height : %f", self.codeTextView.contentSize.height);

if (initialSize.height / self.codeTextView.contentSize.height == 1) {
    isFirstLine = YES;
}

while (startOfLine > 0 && isFirstLine == NO) {
    NSRange delimiter = [head rangeOfCharacterFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] 
                                              options:NSBackwardsSearch range:NSMakeRange(0, startOfLine)];
    startOfLine = delimiter.location;
    NSString *tempHead = [head substringToIndex:startOfLine];
    CGSize tempHeadSize = [tempHead sizeWithFont:self.codeTextView.font constrainedToSize:CGSizeMake(self.codeTextView.frame.size.width, 
                                                                                                     self.codeTextView.frame.size.width)];

    int beforeLine = initialSize.height / self.codeTextView.contentSize.height;
    int afterLine = tempHeadSize.height / self.codeTextView.contentSize.height;

    if (beforeLine != afterLine) 
        NSLog(@"break");
    break;
}

NSString *tail;
if (isFirstLine == NO) {
    tail = [head substringFromIndex:(startOfLine + deviationLocation)];
}else {
    tail = [head substringToIndex:startOfLine - deviationLocation];
}

CGSize lineSize = [tail sizeWithFont:self.codeTextView.font forWidth:self.codeTextView.frame.size.width lineBreakMode:UILineBreakModeWordWrap];

cursor = origin;
cursor.x += lineSize.width;
cursor.y += initialSize.height - lineSize.height;

self.codeTextView.selectedRange = originalPosition;

[self.codeTextView becomeFirstResponder];

NSLog(@"cursor x : %f, y : %f", cursor.x, cursor.y);

}

私は textViewShouldBeginEditing メソッドでそのメソッドを呼び出しました、これは実装です:

-(BOOL)textViewShouldBeginEditing:(UITextView *)textView{

[self getCursorPosition];

self.viewTextViewScroll.contentSize = CGSizeMake(self.codeTextView.frame.size.width, self.codeTextView.contentSize.height+100);

CGRect frameCode = self.codeTextView.frame;
frameCode.size.height = self.codeTextView.contentSize.height + 103;
self.codeTextView.frame = frameCode;

CGRect frameLine = self.lineNumberTextView.frame;
frameLine.size.height = self.codeTextView.contentSize.height +100;
self.lineNumberTextView.frame = frameLine;


return YES;

}

誰か助けてくれませんか

アップデート :

私はこの問題を解決しました.textViewDidChangeSelectionデリゲートメソッドを使用して、私が作成したコードは次のとおりです:

-(void)textViewDidChangeSelection:(UITextView *)textView{
counterAppear++;

if (counterAppear == 1) {

}
else if (counterAppear == 2) {
    isFistAppear = NO;
    codeBuilderSelectedRange = textView.selectedRange;

    [self getCursorPosition];
    CGFloat xPos = cursor.x - (0.5*self.view.frame.size.width);

    if (cursor.x < self.view.frame.size.width) {
        [[[self.viewCodeTextView subviews] lastObject] setContentOffset:CGPointMake(0, cursor.y) animated:YES];
    }else {
        [[[self.viewCodeTextView subviews] lastObject] setContentOffset:CGPointMake(xPos, cursor.y) animated:YES];
    }


}else if (isFistAppear == NO) { //kondisi saat keyboard masih appear & user pindah2 kursor
    codeBuilderSelectedRange = textView.selectedRange;
    [self getCursorPosition];
    NSLog(@"cursor x :%f, y : %f", cursor.x, cursor.y);
}

}

私はBOOL isFirstAppearをviewDidLoadに設定しました。これを設定したのは、textViewDidChangeSelectionのselectedRange.location値をnslogした後、常に2回呼び出され、最初の値は常に見つからない値を与えますが、2番目の値は正しい値を与えるので、設定しますそのように。キーボードメソッドで設定した counterAppear (viewDidLoad で NSNotification によって呼び出されるメソッドを作成しました)。counterAppear は、テキストビューをタップしたときに差分条件を与える値です。

4

1 に答える 1

1

textViewDidBeginEditingでは、場所の値が間違っている場合があります。これを修正するには、次のようにします。

-(void)textViewDidBeginEditing:(UITextView *)textView {
[self performSelector:@selector(beginEditing:) withObject:textView afterDelay:0]; }-(void)beginEditing:(UITextView*)sender {
//code here }
于 2011-03-05T22:19:26.897 に答える