Ich versuche, das Rect für eine zugewiesene Zeichenfolge abzurufen, aber der Aufruf von boundingRectWithSize berücksichtigt nicht die Größe, die ich übergebe, und gibt ein Rect mit einer einzelnen Zeilenhöhe im Gegensatz zu einer großen Höhe zurück (es ist eine lange Zeichenfolge). Ich habe experimentiert, indem ich einen sehr großen Wert für die Höhe und auch 0 wie im folgenden Code übergeben habe, aber das zurückgegebene Rect ist immer das gleiche.
CGRect paragraphRect = [attributedText boundingRectWithSize:CGSizeMake(300,0.0)
options:NSStringDrawingUsesDeviceMetrics
context:nil];
Ist das kaputt oder muss ich etwas anderes tun, damit es einen Fehler für umbrochenen Text zurückgibt?
objective-c
nsattributedstring
RunLoop
quelle
quelle
lineBreakMode
?Antworten:
Sieht so aus, als hätten Sie nicht die richtigen Optionen angegeben. Geben Sie zum Verpacken von Etiketten mindestens Folgendes an:
Hinweis: Wenn die ursprüngliche Textbreite unter 300 liegt. Wenn kein Zeilenumbruch erfolgt, stellen Sie sicher, dass die gebundene Größe korrekt ist. Andernfalls erhalten Sie immer noch falsche Ergebnisse.
quelle
ceilf(paragraphRect.size.height)
damit es aufgerundet wird. Ich vergesse das die ganze Zeit und frage mich, warum meine Etiketten immer noch beschneiden.boundingRectWithSize:
Berechnungen immer in CGRectIntegral (), wodurchCGRectIntegral rounds the rectangle’s origin downward and its size upward to the nearest whole integers
in diesem Fall Höhe und Breite aufgerundet werden , um sicherzustellen, dass kein Beschneiden auftritt, wenn Höhe oder Breite ein Bruchwert sind.Aus irgendeinem Grund gibt boundingRectWithSize immer eine falsche Größe zurück. Ich habe eine Lösung gefunden. Für UItextView -sizeThatFits gibt es eine Methode, die die richtige Größe für den Textsatz zurückgibt. Erstellen Sie also anstelle von boundingRectWithSize eine UITextView mit einem zufälligen Frame und rufen Sie deren sizeThatFits mit der jeweiligen Breite und CGFLOAT_MAX-Höhe auf. Es wird die Größe zurückgegeben, die die richtige Höhe hat.
Wenn Sie die Größe in einer while-Schleife berechnen, vergessen Sie nicht, hinzuzufügen, dass in einem Autorelease-Pool, da n UITextView erstellt wird, der Laufzeitspeicher der App erhöht wird, wenn wir keinen Autoreleasepool verwenden.
quelle
UITextView
so viele Zeit zu erstellen, wie dieheightForRowAtIndexPath
Methode aufgerufen wird? es braucht ZeitEd McManus hat sicherlich einen Schlüssel geliefert, um dies zum Laufen zu bringen. Ich habe einen Fall gefunden, der nicht funktioniert
rect hat nicht die richtige Höhe. Beachten Sie, dass ein anderer String (der an eine Zeichenfolge angehängt wird ) ohne ein Attributwörterbuch initialisiert wurde. Dies ist ein legitimer Initialisierer für einen anderen String, aber boundingRectWithSize: gibt in diesem Fall keine genaue Größe an.
quelle
NSMutableAttributedString
ohne Attribute verwendet und die falsche Größe erhalten.Meine endgültige Entscheidung nach langer Untersuchung: Die
- boundingRectWithSize
Funktion gibt die richtige Größe nur für eine ununterbrochene Zeichenfolge zurück! Falls die Zeichenfolge Leerzeichen oder etwas anderes enthält (von Apple "Einige der Glyphen" genannt) - ist es unmöglich, die tatsächliche Größe des für die Anzeige von Text erforderlichen Rect zu ermitteln!Ich habe Leerzeichen in meinen Zeichenfolgen durch Buchstaben ersetzt und sofort das richtige Ergebnis erhalten.
Apple sagt hier: https://developer.apple.com/documentation/foundation/nsstring/1524729-boundingrectwithsize
"Diese Methode gibt die tatsächlichen Grenzen der Glyphen in der Zeichenfolge zurück. Einige der Glyphen (z. B. Leerzeichen) dürfen die Layoutbeschränkungen überlappen, die durch die übergebene Größe angegeben werden, in einigen Fällen auch den Breitenwert der Größenkomponente von Der zurückgegebene
CGRect
Wert kann den Breitenwert des Größenparameters überschreiten. "Es ist also notwendig, einen anderen Weg zu finden, um die tatsächliche ...
Nach langem Untersuchungsprozess endlich Lösung gefunden !!! Ich bin nicht sicher, ob es in allen Fällen gut funktioniert
UITextView
, aber die wichtigste und wichtigste Sache wurde entdeckt!boundingRectWithSize
Funktion sowieCTFramesetterSuggestFrameSizeWithConstraints
(und viele andere Methoden) berechnen Größe und Textanteil korrekt, wenn das richtige Rechteck verwendet wird. Zum Beispiel -UITextView
hattextView.bounds.size.width
- und dieser Wert ist kein tatsächliches Rechteck, das vom System beim Zeichnen von Text verwendet wirdUITextView
.Ich fand sehr interessante Parameter und führte eine einfache Berechnung im Code durch:
Und Magie funktioniert - alle meine Texte sind jetzt korrekt berechnet! Genießen!
quelle
Schnelle vier Version
Das Messen des Texts mit dem CTFramesetter funktioniert am besten, da er ganzzahlige Größen bietet und Emojis und andere Unicode-Zeichen gut verarbeitet.
quelle
Ich hatte mit keinem dieser Vorschläge Glück. Meine Zeichenfolge enthielt Unicode-Aufzählungszeichen, und ich vermute, dass sie bei der Berechnung Kummer verursachten. Ich bemerkte, dass UITextView die Zeichnung gut handhabte, also habe ich darauf geachtet, um die Berechnung zu nutzen. Ich habe Folgendes getan, was wahrscheinlich nicht so optimal ist wie die NSString-Zeichenmethoden, aber zumindest genau. Es ist auch etwas optimaler als das Initialisieren einer UITextView, um sie nur aufzurufen
-sizeThatFits:
.quelle
Falls Sie einen Begrenzungsrahmen erhalten möchten, indem Sie den Schwanz abschneiden, kann Ihnen diese Frage helfen.
quelle
Es stellt sich heraus, dass für JEDEN Teil eines NSAttributedString ein Wörterbuch mit mindestens NSFontAttributeName und NSForegroundColorAttributeName festgelegt sein muss, wenn Sie möchten, dass boundingRectWithSize tatsächlich funktioniert!
Ich sehe das nirgendwo dokumentiert.
quelle
@ Warrenm Tut mir leid zu sagen, dass die Framesetter-Methode bei mir nicht funktioniert hat.
Ich habe dies erhalten. Diese Funktion kann uns helfen, die Frame-Größe zu bestimmen, die für einen Zeichenfolgenbereich eines NSAttributedString im iPhone / Ipad SDK für eine bestimmte Breite benötigt wird:
Es kann für eine dynamische Höhe von UITableView-Zellen verwendet werden
Dank HADDAD ISSA >>> http://haddadissa.blogspot.in/2010/09/compute-needed-heigh-for-fixed-width-of.html
quelle
#import <CoreText/CoreText.h>
Ich habe festgestellt, dass die bevorzugte Lösung keine Zeilenumbrüche behandelt.
Ich habe festgestellt, dass dieser Ansatz in allen Fällen funktioniert:
quelle
Ich hatte das gleiche Problem damit, mit diesen Techniken keine genaue Größe zu erhalten, und ich habe meinen Ansatz geändert, damit es funktioniert.
Ich habe eine lange zugeschriebene Zeichenfolge, die ich versucht habe, in eine Bildlaufansicht einzufügen, damit sie richtig angezeigt wird, ohne abgeschnitten zu werden. Was ich getan habe, damit der Text zuverlässig funktioniert, war, die Höhe überhaupt nicht als Einschränkung festzulegen und stattdessen die intrinsische Größe übernehmen zu lassen. Jetzt wird der Text korrekt angezeigt, ohne abgeschnitten zu werden, und ich muss die Höhe nicht berechnen.
Ich nehme an, wenn ich die Höhe zuverlässig ermitteln müsste, würde ich eine Ansicht erstellen, die ausgeblendet ist, und diese Einschränkungen und die Höhe des Rahmens ermitteln, sobald die Einschränkungen angewendet werden.
quelle
Ich bin etwas spät dran - aber ich habe versucht, einen Weg zu finden, wie ich den Begrenzungsrahmen finden kann, der um eine zugeordnete Zeichenfolge passt, um einen Fokusring zu erzeugen, wie es beim Bearbeiten einer Datei im Finder der Fall ist. Alles, was ich versucht hatte, schlug fehl, wenn am Ende der Zeichenfolge Leerzeichen oder mehrere Leerzeichen in der Zeichenfolge stehen.
boundingRectWithSize
scheitert kläglich daranCTFramesetterCreateWithAttributedString
.Die Verwendung
NSLayoutManager
des folgenden Codes scheint in allen bisher gefundenen Fällen den Trick zu tun und gibt ein Rect zurück, das die Zeichenfolge perfekt begrenzt. Bonus: Wenn Sie den Text auswählen, gehen die Kanten der Auswahl bis an die Grenzen des zurückgegebenen Rect. Der folgende Code verwendet den layoutManager von aNSTextView
.quelle
Funktioniert auf allen Schriftarten perfekt!
quelle
Ich hatte das gleiche Problem, aber ich erkannte, dass die Höhenbeschränkung korrekt eingestellt wurde. Also habe ich folgendes gemacht:
quelle
Ich habe alles auf dieser Seite ausprobiert und hatte immer noch einen Fall für ein UILabel, das nicht richtig formatiert war. Das tatsächliche Setzen des Attributtextes auf dem Etikett hat das Problem endgültig behoben.
quelle
Eine Sache, die mir aufgefallen ist, ist, dass das Rechteck, von dem ich zurückkommen
(CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(NSDictionary *)attributes context:(NSStringDrawingContext *)context
würde, eine größere Breite haben würde als das, was ich eingegeben habe. Wenn dies passiert ist, wird meine Zeichenfolge abgeschnitten. Ich habe es so gelöst:Für etwas mehr Kontext; Ich hatte mehrzeiligen Text und versuchte, die richtige Höhe für die Anzeige zu finden. BoundRectWithSize gab manchmal eine Breite zurück, die größer war als angegeben. Wenn ich also meine Vergangenheit in der Breite und die berechnete Höhe für die Anzeige meines Textes verwendete, wurde diese angezeigt würde abschneiden. Nach dem Testen, wenn boundingRectWithSize die falsche Breite verwendet hat, betrug der Betrag, um den die Höhe verkürzt wurde, 1 Zeile. Daher würde ich prüfen, ob die Breite größer ist, und in diesem Fall die Zeilenhöhe der Schriftart hinzufügen, um genügend Speicherplatz bereitzustellen, um ein Abschneiden zu vermeiden.
quelle
Wenn der Rahmen des Etiketts nicht 10 addiert, funktioniert diese Methode niemals! hoffe das kann dir helfen! Viel Glück.
quelle
}}
quelle
Ich möchte meine Gedanken hinzufügen, da ich genau das gleiche Problem hatte.
Ich habe es verwendet,
UITextView
da es eine schönere Textausrichtung hatte (begründen, was zu diesem Zeitpunkt nicht verfügbar warUILabel
), aber um nicht interaktiv-nicht scrollbar zu "simulieren"UILabel
, habe ich das vollständige Scrollen, Bouncen und die Benutzerinteraktion deaktiviert .Das Problem war natürlich, dass der Text dynamisch war und die Breite zwar festgelegt wurde, die Höhe jedoch jedes Mal neu berechnet werden sollte, wenn ich einen neuen Textwert festlegte.
boundingRectWithSize
Es funktionierte überhaupt nicht gut für mich, soweit ich sehen konnte,UITextView
fügte ich oben einen Rand hinzu, derboundingRectWithSize
nicht gezählt werden konnte. Daher war die Höhe, aus der abgerufenboundingRectWithSize
wurde, kleiner als sie sein sollte.Da der Text nicht schnell aktualisiert werden sollte, sondern nur für einige Informationen verwendet wird, die möglicherweise alle 2-3 Sekunden am häufigsten aktualisiert werden, habe ich mich für folgenden Ansatz entschieden:
* Der obige Code wird nicht direkt von meiner Quelle kopiert, ich musste ihn anpassen / aus einer Reihe anderer Dinge entfernen, die für diesen Artikel nicht benötigt werden. Nehmen Sie es nicht für Copy-Paste-and-It-Will-Work-Code.
Offensichtlicher Nachteil ist, dass es für jeden Anruf eine Zuweisung und Freigabe hat.
Aber Vorteil ist , dass Sie vermeiden , je nach Kompatibilität zwischen dem, wie boundingRectWithSize zieht Text und berechnet seine Größe und Umsetzung von Text in Zeichnung
UITextView
(oderUILabel
die auch können Sie verwenden , ersetzen Sie einfachUITextView
mitUILabel
). Alle "Fehler", die Apple möglicherweise hat, werden auf diese Weise vermieden.PS Es scheint, dass Sie diese "Temperatur" nicht brauchen sollten
UITextView
und einfachsizeThatFits
direkt vom Ziel fragen können, aber das hat bei mir nicht funktioniert. Obwohl die Logik sagen würde, dass es funktionieren sollte und die Zuweisung / Freigabe von temporärenUITextView
nicht erforderlich ist, war dies nicht der Fall . Aber diese Lösung funktionierte einwandfrei für jeden Text, den ich einfügen würde.quelle
Ok, also habe ich viel Zeit damit verbracht, dies zu debuggen. Ich fand heraus, dass die maximale Texthöhe, wie sie durch definiert ist
boundingRectWithSize
, Text von meinem anzeigen darfUITextView
wurde, niedriger als die Rahmengröße war.In meinem Fall ist der Frame höchstens 140pt, aber die UITextView toleriert höchstens 131pt Texte.
Ich musste das manuell herausfinden und die "echte" maximale Höhe fest codieren.
Hier ist meine Lösung:
quelle