xcode - create an attributed string out of plain (Android formated) text in swift for iOS -
i reading strings out of localizable.strings contains have in strings.xml of android app
"testshort" = "a <b>short</b>\ntest another<b>bold text</b>";
the bold , and line feed 2 formatting attributes have in texts. trying develop method days without success:
func converttext(inputtext: string) -> nsattributedstring { // here comes conversion representation helvetica 14pt , helvetica-bold 14pt including line feeds. }
my final goal display text in uitextview's attributedtext.
being kinda new swift , ios without knowing objective-c found difficult string manipulations quite different , complex , examples in objective-c. makes harder api methods not available or different in swift in objective-c...
here tried far method body of lot of other posts here:
var test = inputtext.datausingencoding(nsunicodestringencoding, allowlossyconversion: true)! attrstr = nsattributedstring( data: test, options: [nsdocumenttypedocumentattribute: nshtmltextdocumenttype], documentattributes: nil, error: nil)! return attrstr
the main issues here \n
isn't converted , font small , different.
next tried manually bold part of text. seem work that:
var newtext = nsmutableattributedstring(string: inputtext) newtext.addattribute(nsfontattributename, value: uifont(name: "helvetica-bold", size: 14.0)!, range: nsrange(location:2,length:4))
now tried search attributes in text, deleting them , use addattribute kinda that
// start of bold text var range = newtext.rangeofstring("<b>")! // end of bold text var range2 = newtext.rangeofstring("</b>")! // replacing attributes newtext = newtext.stringbyreplacingcharactersinrange(range, withstring: "") newtext = newtext.stringbyreplacingcharactersinrange(range2, withstring: "") // creating range bold => error "'string.index' not convertible 'int'" // how such thing var boldrange = nsmakerange(range.startindex, range2.endindex -3) // setting bold newtext.addattribute(nsfontattributename, value: uifont(name: "helvetica-bold", size: 14.0)!, range: boldrange)
this whole range thing main issue @ moment quite different simple position in string.
this issue great example lack of (or hidden) documentation:
the addattribute
wants nsrange, rangeofstring
seems deliver generic range according error message - there no info it. search documentation button in xcode on rangeofstring()
leads nsstring. searching in there rangeofstring()
says returns nsrange
. clicking on leads info of type alias _nsrange
in turn has 2 nsuinteger properties named location
, length
. startindex , endindex property see in xcode? confusing...
would great if can give me snippets or hints i'm wrong here or method body i'm still hoping not difficult if know ios , swift well. i'm aiming ios 7.1 support if way easier ios 8 fine well.
regarding first method nsattributedstring
:
- the
\n
character in html ordinary white space. line break have replace<br />
first. - the font attributes can controlled html
<span>
, see parsing html nsattributedtext - how set font?.
this gives (now updated swift 2):
func converttext(inputtext: string) -> nsattributedstring { var html = inputtext // replace newline character html line break while let range = html.rangeofstring("\n") { html.replacerange(range, with: "<br />") } // embed in <span> font attributes: html = "<span style=\"font-family: helvetica; font-size:14pt;\">" + html + "</span>" let data = html.datausingencoding(nsunicodestringencoding, allowlossyconversion: true)! let attrstr = try? nsattributedstring( data: data, options: [nsdocumenttypedocumentattribute: nshtmltextdocumenttype], documentattributes: nil) return attrstr! }
regarding second method:
there 2 different rangeofstring()
methods, 1 (swift) string
, 1 (foundation) nsstring
. string
method returns range<string.index>
, nsstring
method returns nsrange
.
converting between these 2 possible complicated. reason in string
each "extended grapheme cluster" counts 1 character, whereas in nsstring
each utf-16 unit counted. extended grapheme cluster can 1 or more utf-16 unit ("😄" 2 utf-16 units, "🇩🇪" four).
the addattribute()
method accepts nsrange
. easiest method solve problem convert swift string nsstring
, work nsrange
only. method this:
func converttext(inputtext: string) -> nsattributedstring { let attrstring = nsmutableattributedstring(string: inputtext) let boldfont = uifont(name: "helvetica-bold", size: 14.0)! var r1 = (attrstring.string nsstring).rangeofstring("<b>") while r1.location != nsnotfound { let r2 = (attrstring.string nsstring).rangeofstring("</b>") if r2.location != nsnotfound && r2.location > r1.location { let r3 = nsmakerange(r1.location + r1.length, r2.location - r1.location - r1.length) attrstring.addattribute(nsfontattributename, value: boldfont, range: r3) attrstring.replacecharactersinrange(r2, withstring: "") attrstring.replacecharactersinrange(r1, withstring: "") } else { break } r1 = (attrstring.string nsstring).rangeofstring("<b>") } return attrstring }
Comments
Post a Comment