在swift for iOS中用普通(Android格式)文本创建一个属性字符串 [英] create an attributed string out of plain (Android formatted) text in swift for iOS

查看:122
本文介绍了在swift for iOS中用普通(Android格式)文本创建一个属性字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从Localizable.strings中读取字符串,其中包含类似于Android应用程序的strings.xml中的基本内容

I am reading strings out of a Localizable.strings which contains something like that which is basically what you have in an strings.xml of an Android app

"testShort" = "A <b>short</b>\ntest with another<b>bold text</b>";

粗体和换行符是我文本中唯一的两个格式属性。我正在尝试开发这样的方法几天没有成功:

The bold and and line feed are the only two formatting attributes I have in my texts. I am trying to develop a method like this for days now without success:

func ConvertText(inputText: String) -> NSAttributedString {
    // here comes the conversion to a representation with Helvetica 14pt and Helvetica-Bold 14pt including line feeds.
}

我的最终目标是在UITextView的attributedText中显示文本。

My final goal is to display the text in an UITextView's attributedText.

在不了解Objective-C的情况下对Swift和iOS有点新意我发现很难做String操作,因为它们非常不同且复杂,所有示例都在Objective-C中。更令人难以理解的是,大多数API方法在Swift中不可用或与Objective-C不同...

Being kinda new to Swift and iOS without knowing Objective-C I found its very difficult to do String manipulations as they are quite different and complex and all examples are in Objective-C. What makes it even harder is that most API methods are not available or different in Swift than in Objective-C...

这是我到目前为止尝试的方法在这里有许多其他帖子的帮助:

Here is what I tried so far for the method body with the help of a 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

这里的主要问题是 \ n 未转换,字体非常小且不同。

The main issues here are that \n isn't converted and the font is very small and different.

接下来我尝试手动加粗文本的一部分。它似乎是这样的:

Next I tried to manually bold a part of a text. It seem to work like that:

var newText = NSMutableAttributedString(string: inputText)
newText.addAttribute(NSFontAttributeName, value: UIFont(name: "Helvetica-Bold", size: 14.0)!, range: NSRange(location:2,length:4))

现在我尝试在文本中搜索属性,删除它们并使用类似的addAttribute

Now I tried to search for the attributes in the text, deleting them and use the addAttribute kinda like 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 a range for bold => error "'String.Index' is not convertible to 'int'"
// how to do such a 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 is my main issue at the moment as its quite different to a simple position in the string.

这个问题是缺少(或隐藏的)文档的一个很好的例子:

This issue is a great example for the lack of (or well hidden) documentation:

addAttribute 想要一个NSRange, rangeOfString 似乎根据我得到的错误信息提供了一个通用范围 - 但是没有关于它的信息。
Xcode上的搜索文档按钮 rangeOfString()会导致NSString。
在那里搜索 rangeOfString()表示它返回 NSRange 。单击它会导致 _NSRange 的类型别名的信息,而这些信息又有两个名为 location 的NSUInteger属性和长度。我在XCode中看到的startIndex和endIndex属性在哪里?非常令人困惑...

The addAttribute wants an NSRange, the rangeOfString seems to deliver a generic Range according to an error message I get - but there is no info about it. The Search Documentation button in Xcode on rangeOfString() leads to NSString. Searching in there for rangeOfString()says it returns NSRange. Clicking on that leads to the info of a type alias for _NSRange which in turn has two NSUInteger properties named location and length. Where is the startIndex and endIndex property I see in XCode? Very confusing...

如果你能给我一些片段或提示,我在这里错了,甚至方法体,因为我仍然希望它如果你很了解iOS和Swift,那就太难了。我的目标是支持iOS 7.1,但如果iOS 8的使用方式更简单,那么也很好。

Would be great if you can give me some snippets or hints where I'm wrong here or even the method body as I'm still hoping its not too difficult if you know iOS and Swift well. I'm aiming for iOS 7.1 support but if its way easier with iOS 8 only its fine as well.

推荐答案

关于你的第一个方法 NSAttributedString

  • The \n character in HTML is just ordinary white space. To get a line break you would have to replace it by <br /> first.
  • The font attributes can be controlled by a HTML <span>, see Parsing HTML into NSAttributedText - how to set font?.

这给出了(现在更新为Swift 2):

This gives (now updated for Swift 2):

func convertText(inputText: String) -> NSAttributedString {

    var html = inputText

    // Replace newline character by HTML line break
    while let range = html.rangeOfString("\n") {
        html.replaceRange(range, with: "<br />")
    }

    // Embed in a <span> for 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 your second method:

有两种不同的 rangeOfString()方法,一种用于(Swift) String 和一个
(基础) NSString String 方法返回 Range< String.Index>
NSString 方法返回 NSRange

There are two different rangeOfString() methods, one for (Swift) String and one for (Foundation) NSString. The String method returns a Range<String.Index> and the NSString method returns an NSRange.

这篇关于在swift for iOS中用普通(Android格式)文本创建一个属性字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆