업데이트 :NSMutableAttributedString은 0이 아닌 인덱스에서 시작하는 속성을 표시하지 않습니다.
정말 간단한 독립 실행 형 프로젝트를 만들어 버그를 보여줍니다. 만약 누군가가 같은 것을 당기고 내가 잘못한 곳을 발견 할 수 있다면, 나는 그것을 감사 할 것입니다. 살펴볼 코드가별로 없습니다. 여기에 공개 Repo : https://github.com/reidnez/NSAttributedStringBugDemo
나는 여기에 아주 이상한 문제가 있습니다 : 나는 tableview 있습니다. 각 셀에는 1-3 단어로 된 제목 레이블과 여러 개의 CSV 키워드가있는 레이블 레이블이 있습니다. 나는 또한 검색 막대가 있습니다. 요구 사항은 사용자가 검색 창에 입력 할 때 각 셀의 제목과 키워드 모두에서 부분 일치가 강조 표시됩니다. 스크린 샷 :
첫 번째 이미지가 A-좋아합니다. 두 번째 이미지에서 제목 레이블의 "an"을 강조 표시해야합니다. 그러나 알 수 있듯이,별로 ...
위에서 볼 수 있듯이 이것은 "키워드"레이블에서 완벽하게 작동합니다. 이 두 레이블의 속성 문자열은 내가 작성한 범주 (아래 코드)에 의해 작성됩니다. 동일한 메소드가 두 문자열 모두에서 호출되며 디버거가 말한 것과 똑같이 동작하는 것으로 보입니다. UI는 다른 이야기를합니다.
나는 여러 번 디버거를 밟았으며 모든 경우에 특성 문자열 은 올바르게 구성되어 나타납니다.. 또한 뭔가 다른 사람이 [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.
}
댓글이 없습니다. 이런, 고마워. 최고 건설적인! 다시는 그 일을하지 않을 것입니다 ... 내가 무엇을 했든간에? –
테이블 뷰 셀의 라벨과 동일한 것을 보았습니다. 나는 텍스트의 시작 부분에 밑줄을 칠 수는 있지만 중간 부분은 강조하지 않는다. 간단한 테스트 응용 프로그램을 만들어서 애플에 버그 보고서를 제출하는 것이 좋습니다. – rmaddy
"애플의 버그"는 항상 나의 최후의 해결책이다. 나는 그게 사실이라는 것을 증명해야한다. (어쩌면 작은 실수로 어딘가에서 실수를 범할 가능성이 훨씬 더 높다). 그러나 비슷한 문제가 발생하면 실제로 올바른 결론 일 수 있습니다. 독립 실행 형 테스트 응용 프로그램은 훌륭한 아이디어이며, 그렇게 할 것입니다. 감사! –