2014-07-26 9 views
7

Mam UILabel z tweetem jak ciąg, w tym wzmianki o innych użytkownikach.layoutManager boundingRectForGlyphRange: inTextContainer: nie działa dla wszystkich ciągów znaków

Hey @stephen and @frank and @Jason1. 

Próbuję umieścić każdą wzmiankę w tappable, aby załadować profil tego użytkownika. Znalazłem kod z innego wpisu SO (How do I locate the CGRect for a substring of text in a UILabel?), którego mogłem użyć, aby zlokalizować pozycję każdej wzmianki w ciągu. Jednak zwykle nie działa dla ostatnich lub ostatnich 2 wzmianek w poście.

Metoda z tak postu (nieco zmodyfikowane):

- (CGRect)boundingRectForCharacterRange:(NSRange)range 
{ 
    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithAttributedString:self.myLabel.attributedText]; 
    NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:attributedString]; 
    NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init]; 
    [textStorage addLayoutManager:layoutManager]; 
    NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:self.myLabel.bounds.size]; 
    textContainer.lineFragmentPadding = 0; 
    [layoutManager addTextContainer:textContainer]; 

    NSRange glyphRange; 

    // Convert the range for glyphs. 
    [layoutManager characterRangeForGlyphRange:range actualGlyphRange:&glyphRange]; 

    return [layoutManager boundingRectForGlyphRange:glyphRange inTextContainer:textContainer]; 
} 

Następnie w touchesEnded:, że pętla nad każdą wzmiankę, uzyskać zasięg w głównym ciągu, i sprawdzić, czy dotyk jest wewnątrz tego CGRect .

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{   
    UITouch *touch = touches.allObjects[0]; 

    for (NSString *mention in self.mentions) { 
     NSRange range = [self.postText rangeOfString:mention options:NSCaseInsensitiveSearch]; 
     CGRect rect = [self boundingRectForCharacterRange:range]; 
     NSLog(@"rect for %@ is %@", mention, NSStringFromCGRect(rect)); 
    } 
} 

// Output from above 
rect for @stephen is {{33.388, 0}, {72.471001, 20.553001}} 
rect for @frank is {{143.021, 0}, {49.809998, 20.553001}} 
rect for @Jason1 is {{0, 0}, {0, 0}} 

Działa to znakomicie przez większość czasu, jednak @ Jason1 nie jest dopasowany. Zmieniłem kolejność nazw i zawsze jest ostatnia. Moja etykieta oblewa się, ale wciąż pasuje do nazw na drugiej i trzeciej linii. Czy jest jakieś ustawienie lub coś, czego mi brakuje? Próbowałem zmienić rozmiar i czcionkę etykiet, ale bez powodzenia. Naprawdę tu jestem.

+1

Czy udało się rozwiązać problem? Podziel się rozwiązaniem, jeśli masz. –

Odpowiedz

10

Rozwiązaniem tego problemu nie jest ustawienie ograniczenia wysokości podczas inicjowania kontenera NSTextContainer. Zamiast tego użyj bardzo dużej liczby.

NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:CGSizeMake(self.myLabel.bounds.size.width, CGFLOAT_MAX)]; 
+0

W systemie iOS7 należy użyć tej metody. Ale w systemie iOS8 i nowszych wersjach można używać szczęśliwie etykiety.size. – generalzyq

Powiązane problemy