2014-09-20 7 views
6

업데이트 :NSMutableAttributedString은 0이 아닌 인덱스에서 시작하는 속성을 표시하지 않습니다.

정말 간단한 독립 실행 형 프로젝트를 만들어 버그를 보여줍니다. 만약 누군가가 같은 것을 당기고 내가 잘못한 곳을 발견 할 수 있다면, 나는 그것을 감사 할 것입니다. 살펴볼 코드가별로 없습니다. 여기에 공개 Repo : https://github.com/reidnez/NSAttributedStringBugDemo

나는 여기에 아주 이상한 문제가 있습니다 : 나는 tableview 있습니다. 각 셀에는 1-3 단어로 된 제목 레이블과 여러 개의 CSV 키워드가있는 레이블 레이블이 있습니다. 나는 또한 검색 막대가 있습니다. 요구 사항은 사용자가 검색 창에 입력 할 때 각 셀의 제목과 키워드 모두에서 부분 일치가 강조 표시됩니다. 스크린 샷 :

Everything looks as it should searching on "Fa"

"an" highlights keyword, but not title

첫 번째 이미지가 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. 
} 
+0

댓글이 없습니다. 이런, 고마워. 최고 건설적인! 다시는 그 일을하지 않을 것입니다 ... 내가 무엇을 했든간에? –

+2

테이블 뷰 셀의 라벨과 동일한 것을 보았습니다. 나는 텍스트의 시작 부분에 밑줄을 칠 수는 있지만 중간 부분은 강조하지 않는다. 간단한 테스트 응용 프로그램을 만들어서 애플에 버그 보고서를 제출하는 것이 좋습니다. – rmaddy

+0

"애플의 버그"는 항상 나의 최후의 해결책이다. 나는 그게 사실이라는 것을 증명해야한다. (어쩌면 작은 실수로 어딘가에서 실수를 범할 가능성이 훨씬 더 높다). 그러나 비슷한 문제가 발생하면 실제로 올바른 결론 일 수 있습니다. 독립 실행 형 테스트 응용 프로그램은 훌륭한 아이디어이며, 그렇게 할 것입니다. 감사! –

답변

2

이 글을 써 주셔서 감사합니다 ... 나는 너무 미쳤다고 생각했습니다.

Apple에서 공식적인 것을 기다리는 동안 나는 해킹 (read : hack)을 생각해 냈습니다.

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

고마워요! 나는 오래 전에이 문제를 해결하고 다른 일을하기 시작했습니다. 하지만 ... 집에 도착하자마자, 나는 이것을 시험해보고 (당신이 대답한다고 생각하면) 대답을 받아 들일 것입니다. –

+0

이 해킹은 나를 위해 일했습니다 .. –

+0

@ReidBelton : 어떻게되는지 알 수 있습니다 :) –