我正在爲iPad開發一個簡單的書寫應用程序。如何在UITextView中查找遊標的像素位置?
我在計算UITextView
中游標的像素位置。我花了幾個星期的時間來設計這個,但我仍然無法想象要做到這一點。
在stackoverflow中,Tony寫了一個很好的算法來找到遊標的像素位置。
Pixel-Position of Cursor in UITextView
我實現了這個帶着些許的修改,它幾乎工程,它給光標的正確的像素位置。但是,它只適用於英文字母。
如果在行尾有中文或日文字符,則UITextView
執行字符換行而不是換行,即使中文字符之間沒有空格。我認爲當UITextView
只執行文字換行(用英文字母表示)時,Tony的算法才起作用。
有沒有其他方法可以在UITextView
中找到光標的像素位置?
還是有一種方法來確定一個特定的字符是否如下字符的包裝像中國的文字或文字環繞喜歡英語嗎?
增加:
這是我的實現基於託尼的算法。我以橫向模式放置了一個UITextView
,因此其寬度爲1024,我使用大小爲21的自定義字體。您應該適當更改sizeOfContentWidth
和sizeOfContentLine
。 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);
你能分享你對託尼的進行的修改,因爲我敢肯定,許多人正在尋找如何找到光標/光標的像素位置的答案。謝謝。 – Joshua 2010-10-13 06:08:39
嗨,我添加了基於Tony算法的實現。 Tony算法的一個補充是,在開始時,我將當前光標移動到單詞的末尾。 – pnmn 2010-10-13 06:57:25
該算法基於UITextView僅進行單詞換行的假設。我認爲我們需要一種不同的方法來計算光標的正確像素位置,以使其適用於任何類型的角色。一種解決方案是,我們可以從頭開始使用CoreText,UITextInput和UIKeyInput來創建全新的自定義文本視圖,但我不想僅爲光標位置執行此操作。 – pnmn 2010-10-13 07:20:19