gpt4 book ai didi

ios - 如何在 UITextView 中找到光标的像素位置?

转载 作者:可可西里 更新时间:2023-11-01 03:58:37 27 4
gpt4 key购买 nike

我正在为 iPad 开发一个简单的写作应用程序。

我正在尝试计算 UITextView 中光标的像素位置。我花了几个星期来设计这个,但我仍然想不出办法去做。

在 stackoverflow 中,Tony 写了一个很好的算法来找到光标的像素位置。

Pixel-Position of Cursor in UITextView

我通过一点修改来实现它,它几乎可以提供正确的光标像素位置。但是,它仅适用于英文字母。

如果行尾有中文或日文字符,UITextView 执行字符换行,而不是文字换行,即使中文字符之间没有空格。我认为 Tony 的算法在 UITextView 仅执行自动换行(使用英文字母)时有效。

有没有其他方法可以在 UITextView 中找到光标的像素位置?

或者有没有办法判断一个特定的字符是像汉字一样进行换行还是像英文一样进行换行?

添加:

这是我基于 Tony 算法的实现。我在横向模式下放置了一个 UITextView,因此它的宽度为 1024,并且我使用了大小为 21 的自定义字体。您应该更改 sizeOfContentWidthsizeOfContentLine适当。 sizeOfContentWidth小于实际宽度,sizeOfContentLine大于实际字号(行高>字号)。

抱歉乱码和评论!还有一些小错误,如果你在行尾输入汉字(没有自动换行),它会给出错误的位置。

#define sizeOfContentWidth 1010
#define sizeOfContentHeight 1000
#define sizeOfContentLine 25

// Stores the original position of the cursor
NSRange originalPosition = textView.selectedRange;

// Computes textView's origin
CGPoint origin = textView.frame.origin;

// Checks whether a character right to the current cursor is a non-space character
unichar c = ' ';

if(textView.selectedRange.location != [textView.text length])
c = [textView.text characterAtIndex:textView.selectedRange.location];

// If it's a non-space or newline character, then the current cursor moves to the end of that word
if(c != 32 && c != 10){
NSRange delimiter = [textView.text rangeOfCharacterFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]
options:NSLiteralSearch
range:NSMakeRange(textView.selectedRange.location, [textView.text length] - textView.selectedRange.location)];

if(delimiter.location == NSNotFound){
delimiter.location = [textView.text length];
}

textView.selectedRange = delimiter;
}

// Deviation between the original cursor location and moved location
int deviationLocation = textView.selectedRange .location - originalPosition.location;

// Substrings the part before the cursor position
NSString* head = [textView.text substringToIndex:textView.selectedRange.location];

// Gets the size of this part
CGSize initialSize = [head sizeWithFont:textView.font constrainedToSize:CGSizeMake(sizeOfContentWidth, sizeOfContentHeight)];

// Gets the length of the head
NSUInteger startOfLine = [head length];

// The first line
BOOL isFirstLine = NO;

if(initialSize.height / sizeOfContentLine == 1){
isFirstLine = YES;
}

while (startOfLine > 0 && isFirstLine == NO) {
// 1. Adjusts startOfLine to the beginning of the first word before startOfLine
NSRange delimiter = [head rangeOfCharacterFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] options:NSBackwardsSearch range:NSMakeRange(0, startOfLine)];

// Updates startsOfLine
startOfLine = delimiter.location;

// 2. Check if drawing the substring of head up to startOfLine causes a reduction in height compared to initialSize.
NSString *tempHead = [head substringToIndex:startOfLine];

// Gets the size of this temp head
CGSize tempHeadSize = [tempHead sizeWithFont:textView.font constrainedToSize:CGSizeMake(sizeOfContentWidth, sizeOfContentHeight)];

// Counts the line of the original
int beforeLine = initialSize.height / sizeOfContentLine;

// Counts the line of the one after processing
int afterLine = tempHeadSize.height / sizeOfContentLine;

// 3. If so, then you've identified the start of the line containing the cursor, otherwise keep going.
if(beforeLine != afterLine)
break;
}

// Substrings the part after the cursor position
NSString* tail;

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

// Gets the size of this part
CGSize lineSize = [tail sizeWithFont:textView.font forWidth:sizeOfContentWidth lineBreakMode:UILineBreakModeWordWrap];

// Gets the cursor position in coordinate
CGPoint cursor = origin;
cursor.x += lineSize.width;
cursor.y += initialSize.height - lineSize.height;

// Back to the original position
textView.selectedRange = originalPosition;

// Debug
printf("x: %f, y: %f\n", cursor.x, cursor.y);

最佳答案

如果你只针对 IOS7,你可以使用UITextView 方法:

- (CGRect)caretRectForPosition:(UITextPosition *)position;

小样本:

NSRange range; // target location in text that you should get from somewhere, e.g. textview.selectedRange
UITextView textview; // the text view

UITextPosition *start = [textview positionFromPosition:textview.beginningOfDocument offset:range.location];
CGRect caretRect = [self caretRectForPosition:start]; // caret rect in UITextView

关于ios - 如何在 UITextView 中找到光标的像素位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3920944/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com