2014-09-20 61 views
6

更新:NSMutableAttributedString將不會顯示從非零索引開始的屬性

我創建了一個非常簡單的獨立項目來演示該錯誤。如果有人想拉同一件事,看看他們能否發現我出錯的地方,我一定會很感激。沒有太多代碼需要查看。公開回購這裏: https://github.com/reidnez/NSAttributedStringBugDemo

我在這裏有一個很奇怪的問題:我有一個tableview。每個單元格有一個標題標籤有1-3個字,和一個關鍵字標籤有幾個CSV關鍵字。我也有一個搜索欄。要求是,當用戶鍵入搜索欄時,每個單元格的標題和關鍵字上的任何部分匹配都會突出顯示。截圖:

Everything looks as it should searching on "Fa"

"an" highlights keyword, but not title

第一圖像是,好吧。在第二張圖片中,標題標籤的「an」應該突出顯示。但是,正如你所看到的,不是那麼多......

這個工作完全正確的「關鍵字」標籤,你可以看到上面。這兩個標籤的屬性字符串是由我寫的類別(代碼如下)創建的。兩個字符串都調用了相同的方法,並且從調試器告訴我的行爲看起來相同。用戶界面講述了不同的故事。

我已經遍歷調試器多次,並且在所有情況下,屬性字符串出現已被正確配置。我還驗證了別的東西不是調用[tableView reloadData],我的代碼中沒有其他地方覆蓋標籤的值。這是怎麼匹配「的」爲「方」看在調試器,之前在cellForRowAtIndexPath結束返回細胞:

(lldb) po customCell.entryTitleLabel.attributedText 
F{ 
}an{ 
NSBackgroundColor = "UIDeviceRGBColorSpace 0.533333 0.835294 0.156863 1"; 
}g{ 
} 

我看不錯......這正是我想要的。但是當細胞呈現時,沒有任何亮點可以看到!怪異的是,作爲一個實驗我嘗試了標籤設置,我就在cellForRow創造了一個完全任意attributedString:

NSMutableAttributedString *fake = [[NSMutableAttributedString alloc] initWithString:@"Fang"]; 
      [fake addAttribute:NSBackgroundColorAttributeName value:MATCH_TEXT_HILIGHT_COLOR range:NSMakeRange(1, 2)]; 
      customCell.entryTitleLabel.attributedText = fake; 

這也將失敗。根本沒有突出顯示...但我可以突出顯示範圍{0,1}到{0,fake.length}的任何子字符串,並且其行爲與預期相同。 同樣,它似乎拒絕突出顯示任何不在索引0處開始的子字符串 - 但僅限於標題標籤。

我在想我嗎?我錯過了什麼?

下面是我的類別...但我相當有信心,問題不在於此,因爲它對關鍵字字符串完美起作用,並且(再次)屬性在單元格返回前似乎正確設置:

-(void)hilightMatchingSubstring:(NSString*)substring color:(UIColor*)hilightColor range:(NSRange)range 
{ 
    if ([self.string compare:substring options:NSCaseInsensitiveSearch] == NSOrderedSame) { 
     [self addAttribute:NSBackgroundColorAttributeName value:hilightColor range:NSMakeRange(0, self.length)]; 
     return; 
    } 

    // Sanity check. Make sure a valid range has been passed so that we don't get out-of-bounds crashes. Default to return self wrapped in an attributed string with no attributes. 
    NSRange selfRange = NSMakeRange(0, self.length); 
    if (NSIntersectionRange(selfRange, range).length == 0) { 
     NSLog(@" \n\n\n*** Match range {%lu, %lu} does not intersect main string's range {%lu, %lu}. Aborting *** \n\n\n", (unsigned long)range.location, (unsigned long)range.length, (unsigned long)selfRange.location, (unsigned long)selfRange.length); 
     return; 
    } 

    if (substring.length > 0) { 
     NSRange movingRange = NSMakeRange(range.location, substring.length); 
     if (NSMaxRange(movingRange) > self.length) { 
      return; 
     } 

     NSString *movingString = [self.string substringWithRange:movingRange]; 

     while (NSMaxRange(movingRange) < NSMaxRange(range)) { 
      if ([movingString compare:substring options:NSCaseInsensitiveSearch] == NSOrderedSame) { 
       [self addAttribute:NSBackgroundColorAttributeName value:hilightColor range:movingRange]; 
      } 
      movingRange = NSMakeRange(movingRange.location + 1, substring.length); 
      movingString = [self.string substringWithRange:movingRange]; 
     } 
    } // This is fine...string leaves properly attributed. 
} 
+0

Downvote with no comment?嘖,謝謝。超級建設性!我不會再那樣做......不管我做了什麼? – 2014-09-20 22:34:29

+2

我看到與表格視圖單元格的標籤相同的東西。我可以強調文本的開始,但不是中間的。我建議製作一個簡單的小測試應用程序,然後將錯誤報告提交給Apple。 – rmaddy 2014-09-20 22:40:15

+0

「這是蘋果的錯誤」總是我最後的解決方案......我真的必須向自己證明情況是這樣的(更有可能的是,小我在某處犯了一個錯誤)。但是如果你遇到過類似的問題,那實際上可能是正確的結論。獨立的測試應用程序是一個好主意,我會這樣做。謝謝! – 2014-09-20 22:42:17

回答

2

感謝您寫這篇文章...以爲我也瘋了!

我想出了一個解決方法(閱讀:黑客),而我們等待蘋果官方的東西。

NSDictionary *hackAttribute = [NSDictionary dictionaryWithObjectsAndKeys: 
          [UIColor clearColor], NSBackgroundColorAttributeName, nil]; 

NSMutableAttributedString *attributedText = 
    [[NSMutableAttributedString alloc] initWithString:@"some text..."]; 
    [attributedAddressText setAttributes:hackAttribute range:NSMakeRange(0, attributedText.length)]; 
// Then set your other attributes as per normal 

希望有所幫助。

+0

謝謝!我實際上已經放棄了很久以前的工作,並開始研究其他事情。但是......只要我回家,我會測試這個(假設它有效)接受你的答案。 – 2015-01-09 16:59:41

+0

這個黑客爲我工作.. – 2015-01-16 01:28:08

+0

@ReidBelton:lemme知道它是怎麼回事:) – 2015-01-20 01:59:51