Zeichenindex am Berührungspunkt für UILabel
Für einUILabel
, Ich möchte herausfinden, welcher Charakterindex zu einem bestimmten Zeitpunkt von einem Berührungsereignis empfangen wird. Ich möchte dieses Problem für iOS 7 mit Text Kit lösen.
Da UILabel keinen Zugriff auf seineNSLayoutManager
Ich habe meine eigene basierend auf erstelltUILabel
Die Konfiguration sieht folgendermaßen aus:
- (void)textTapped:(UITapGestureRecognizer *)recognizer
{
if (recognizer.state == UIGestureRecognizerStateEnded) {
CGPoint location = [recognizer locationInView:self];
NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:self.attributedText];
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
[textStorage addLayoutManager:layoutManager];
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:self.bounds.size];
[layoutManager addTextContainer:textContainer];
textContainer.maximumNumberOfLines = self.numberOfLines;
textContainer.lineBreakMode = self.lineBreakMode;
NSUInteger characterIndex = [layoutManager characterIndexForPoint:location
inTextContainer:textContainer
fractionOfDistanceBetweenInsertionPoints:NULL];
if (characterIndex < textStorage.length) {
NSRange range = NSMakeRange(characterIndex, 1);
NSString *value = [self.text substringWithRange:range];
NSLog(@"%@, %zd, %zd", value, range.location, range.length);
}
}
}
Der obige Code befindet sich in aUILabel
Unterklasse mit aUITapGestureRecognizer
konfiguriert, um anzurufentextTapped:
(Kern).
Der resultierende Zeichenindex ist sinnvoll (erhöht sich, wenn Sie von links nach rechts tippen), aber nicht korrekt (das letzte Zeichen wird ungefähr auf der Hälfte der Breite des Etiketts erreicht). Möglicherweise ist die Schriftgröße oder die Größe des Textcontainers nicht richtig konfiguriert, kann das Problem jedoch nicht finden.
Ich möchte meine Klasse wirklich in einer Unterklasse von haltenUILabel
anstatt zu verwendenUITextView
. Hat jemand dieses Problem für gelöstUILabel
?
Aktualisieren: Ich habe ein DTS-Ticket für diese Frage ausgegeben und der Apple-Ingenieur hat empfohlen, sie zu überschreibenUILabel
'sdrawTextInRect:
mit einer Implementierung, die meinen eigenen Layout-Manager verwendet, ähnlich diesem Code-Snippet:
- (void)drawTextInRect:(CGRect)rect
{
[yourLayoutManager drawGlyphsForGlyphRange:NSMakeRange(0, yourTextStorage.length) atPoint:CGPointMake(0, 0)];
}
Ich denke, es wäre eine Menge Arbeit, meinen eigenen Layout-Manager mit den Einstellungen des Etiketts synchron zu halten, also werde ich wahrscheinlich weitermachenUITextView
trotz meiner Präferenz fürUILabel
.
Update 2: Ich entschied mich zu verwendenUITextView
Letztendlich. Der Zweck all dessen bestand darin, Abgriffe auf im Text eingebettete Links zu erkennen. Ich habe versucht zu verwendenNSLinkAttributeName
, aber dieses Setup löste beim schnellen Tippen auf einen Link nicht den Delegate Callback aus. Stattdessen müssen Sie den Link für eine gewisse Zeit drücken - sehr ärgerlich. Also habe ich geschaffenCCHLinkTextView das hat dieses problem nicht.