2013-03-09 51 views
4

我正在使用TTTAttributedLabel將格式應用於文本,但它似乎崩潰,因爲我試圖將格式應用於包含表情符號的範圍。示例:帶有EMOJI導致NSRange問​​題的文本字符串

NSString *text = @"@user1234 #hashtag"; // text.length reported as 22 by NSLog as each emoji is 2 chars in length 
cell.textLabel.text = text; 

int length = 8; 
int start = 13; 

NSRange *range = NSMakeRange(start, length); 

if (!NSEqualRanges(range, NSMakeRange(NSNotFound, 0))) { 
    // apply formatting to TTTAttributedLabel 
    [cell.textLabel addLinkToURL:[NSURL URLWithString:[NSString stringWithFormat:@"someaction://hashtag/%@", [cell.textLabel.text substringWithRange:range]]] withRange:range]; 
} 

注意:我傳遞了來自API的NSRange值以及文本字符串。

在上面我試圖應用格式#hashtag。通常這工作正常,但因爲我有字符串涉及表情符號,我相信範圍標識試圖格式化表情符號,因爲它們實際上是UTF值,它在TTTAttributedLabel導致崩潰(它實際上掛起沒有崩潰,但是。 ..)

奇怪的是,如果有1周的表情符號,但休息,如果有2

誰能幫我找出在這裏做什麼工作好?

+1

如果您要顯示應用格式的代碼,特別是代碼「掛起」,這將更容易診斷。你在這裏顯示的代碼都沒有引用字符串。理想情況下,您應該能夠創建一個非常短的程序來演示問題,以便其他人可以重現該問題。 – 2013-03-09 15:48:00

+0

添加上面顯示我申請使用TTTAttributedLabel addLinkToUrl方法 – mootymoots 2013-03-09 16:00:07

回答

1

我假設這是來自Twitter API,並且您正嘗試使用它們返回的實體字典。我剛剛編寫代碼來支持處理這些範圍以及NSString版本的字符串範圍。

我的做法是「修復」Twitter返回以應付額外字符的實體字典。由於各種原因,我無法共享代碼,但這是我所做的:

  1. 製作實體字典的深層可變副本。
  2. 循環通過串的整個範圍內,通過unicharunichar,這樣做:
    1. 檢查是否unichar是在代理對範圍(0xd800 - >0xdfff)。
    2. 如果它是代理對碼點,則遍歷實體詞典中的所有條目,並且如果它們大於字符串中的當前位置(根據unichar s),則將索引移位1。然後,將循環計數器加1以跳過此代理對的夥伴,因爲它現在已被處理。
    3. 如果它不是代理對,則什麼也不做。
  3. 循環遍歷所有實體並檢查它們是否都沒有溢出字符串的末尾。他們不應該,而只是開始。我發現一些Twitter返回duff數據的情況。

我希望有幫助!我也希望有一天我可以開源這個代碼,因爲我認爲它會非常有用!

+0

其實我試過這個,但是找到了一個更簡單的解決方案。我沒有使用twitter btw,但與實體類似。每個實體都有實體的文本,所以我只查找了整個字符串中的entity.text的範圍,而BINGO則沒有更多的問題。 :) – mootymoots 2013-03-09 23:11:47

+0

哦,太棒了,那很好,然後:-)。雖然我猜如果你有兩個實體具有相同的文本但鏈接到不同的地方。不過,很高興你解決了! – mattjgalloway 2013-03-10 08:47:10

3

問題是,字符串中Unicode值超過\ U10000或更高的任何Unicode字符在NSString中將顯示爲兩個字符。

既然你想要格式化hashtag,你應該使用更多的動態方式來獲取開始和長度值。用NSString rangeOfString找到#字符的位置。使用該結果和字符串的長度來獲得所需的長度。

NSString *text = @"@user1234 #hashtag"; // text.length reported as 22 by NSLog as each emoji is 2 chars in length 
cell.textLabel.text = text; 

NSUInteger start = [text rangeOfString:@"#"]; 
if (start != NSNotFound) { 
    NSUInteger length = text.length - start; 
    NSRange *range = NSMakeRange(start, length); 
    // apply formatting to TTTAttributedLabel 
    [cell.textLabel addLinkToURL:[NSURL URLWithString:[NSString stringWithFormat:@"someaction://hashtag/%@", [cell.textLabel.text substringWithRange:range]]] withRange:range]; 
} 
+1

,如果有一個哈希標籤,但可以有很多,並將匹配非哈希標籤。我寧願使用提供的範圍,並根據表情符號在那裏進行調整。 – mootymoots 2013-03-09 16:20:53

+2

正確的方法是掃描字符串以獲取井號標籤。如果字符串可以包含多個hashtag,那麼您不能硬編碼位置。您必須掃描該標籤的字符串。正確使用'NSString rangeOfStringXXX'方法來查找所有這些方法。我只是給你找到一個例子。這很容易更新,使用循環,找到每個哈希標籤。顯然,長度的確定更多地涉及到然後只是到了字符串的末尾。 – rmaddy 2013-03-09 16:25:39

+0

我在上面添加了一個註釋,它似乎只是一個問題,如果有兩個表情符號在一起,它工作正常,如果有一個表情符號。 – mootymoots 2013-03-09 16:34:19