swift - usedRectForTextContainer size bug with NSAttributedString? -
i attempting calculate minimum height needed nstextview
's content @ set width through following process (where self
instance of nstextview
):
let currentwidth = self.frame.width let textstorage = nstextstorage(attributedstring: self.attributedstring()) let textcontainer = nstextcontainer(containersize: nsmakesize(currentwidth, cgfloat.max)) let layoutmanager = nslayoutmanager() layoutmanager.addtextcontainer(textcontainer) textstorage.addlayoutmanager(layoutmanager) layoutmanager.glyphrangefortextcontainer(textcontainer) let newsize = layoutmanager.usedrectfortextcontainer(textcontainer) heightconstraint.constant = newsize.height
the string created through conversion markdown nsattributedstring
:
let data = styledhtml.datausingencoding(nsutf8stringencoding, allowlossyconversion: false) let attributed = try! nsattributedstring(data: data!, options: [ nsdocumenttypedocumentattribute: nshtmltextdocumenttype ], documentattributes: nil) self.textstorage?.setattributedstring(attributed)
the issue, however, minimum height calculated off 20px (the grey area indicates text, red indicates view):
i figured issue usedrectfortextcontainer()
, when set string
value of nstextview
instance else, i.e.:
self.string = "random string...\ntwo lines" let currentwidth = self.frame.width ...
i correct height:
i haven't found useful on google, other this question has similar issue no solution.
it might worth noting setting grey background through inline style sheet pretty barebones:
*{ margin:0 !important; padding:0 !important; line-height:20px; /*default_font*/ /*default_font_size*/ background:grey; } em{ font-style:italic; }
where /*default_font*/
, /*default_font_size*/
swapped default nsfont
values prior being added html.
edit: it's not html generated causes discrepancy, both have exact same format/styling:
original string:
<!doctype html public "-//w3c//dtd html 4.01//en" "http://www.w3.org/tr/html4/strict.dtd"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta http-equiv="content-style-type" content="text/css"> <title></title> <meta name="generator" content="cocoa html writer"> <meta name="cocoaversion" content="1404.11"> <style type="text/css"> p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; line-height: 20.0px; font: 13.0px 'helvetica neue'; color: #0000ee; -webkit-text-stroke: #0000ee; background-color: #808080} span.s1 {text-decoration: underline ; font-kerning: none} </style> </head> <body> <p class="p1"><span class="s1"><a href="http://www.native-languages.org/houses.htm">http://www.native-languages.org/houses.htm</a></span></p> <p class="p1"><span class="s1"><a href="https://www.youtube.com/watch?v=1ou6__m8to4">https://www.youtube.com/watch?v=1ou6__m8to4</a></span></p> </body> </html>
random string:
<!doctype html public "-//w3c//dtd html 4.01//en" "http://www.w3.org/tr/html4/strict.dtd"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta http-equiv="content-style-type" content="text/css"> <title></title> <meta name="generator" content="cocoa html writer"> <meta name="cocoaversion" content="1404.11"> <style type="text/css"> p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; line-height: 20.0px; font: 13.0px 'helvetica neue'; color: #0000ee; -webkit-text-stroke: #0000ee; background-color: #808080} span.s1 {text-decoration: underline ; font-kerning: none} </style> </head> <body> <p class="p1"><span class="s1"><a href="http://www.native-languages.org/houses.htm">f</a></span></p> </body> </html>
well embarrassing! after testing further, noticed self.attributedstring().string
value had trailing line break \n
, must've been created during conversion html nsattributedstring
. remedied so:
let data = styledhtml.datausingencoding(nsutf8stringencoding, allowlossyconversion: false) let attributed = try! nsmutableattributedstring(data: data!, options: [ nsdocumenttypedocumentattribute: nshtmltextdocumenttype ], documentattributes: nil) let lastcharacterrange = nsmakerange(commentstring.length - 1, 1) let lastcharacter = self.attributedsubstringfromrange(lastcharacterrange) if lastcharacter.string == "\n" { self.deletecharactersinrange(lastcharacterrange) }
basically, changed nsattributedstring
nsmutableattributedstring
, allowing me remove last character through deletecharactersinrange
.
Comments
Post a Comment