【发布时间】:2015-10-19 22:26:51
【问题描述】:
为了能够将 SVG 图像用于从 HTML 创建的属性字符串,我愿意
func createAttributedString(string: String) -> NSMutableAttributedString {
let data = string.dataUsingEncoding(NSUTF8StringEncoding)
let options = [NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute: NSUTF8StringEncoding]
let attributedString = (try! NSMutableAttributedString(
data: data!,
options: options as! [String : AnyObject],
documentAttributes: nil))
var svgImageAttributes: [NSTextAttachment] = []
var svgImageRanges: [NSRange] = []
attributedString.enumerateAttribute("NSAttachment", inRange: NSMakeRange(0, attributedString.length), options: []) { (attribute, range, stop) -> Void in
if let attribute = attribute as? NSTextAttachment, fileType = attribute.fileType where fileType == "public.svg-image"{
svgImageAttributes.append(attribute)
svgImageRanges.append(range)
}
}
let array = Array(zip(svgImageAttributes, svgImageRanges))
for i in array {
let (attachment, range) = i
if let imageData = attachment.fileWrapper?.serializedRepresentation {
var chapterTextAttachment:ChapterImageTextAttachment!
if let preferedImageWidth = self.preferedImageWidth{
chapterTextAttachment = ChapterImageTextAttachment(data: imageData, ofType: attachment.fileType, desiredWidth: preferedImageWidth)
} else {
chapterTextAttachment = ChapterImageTextAttachment(data: imageData, ofType: attachment.fileType)
}
let string = NSMutableAttributedString(string: attributedString.string.substringWithRange(attributedString.string.rangeFromNSRange(range)!), attributes: ["NSAttachment": chapterTextAttachment])
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .Center
string.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: range)
attributedString.replaceCharactersInRange(range, withAttributedString: string)
}
}
return attributedString
}
ChapterImageTextAttachment
class ChapterImageTextAttachment: NSTextAttachment {
let width:CGFloat
var size: CGSize! {
set{
self.bounds = CGRectMake(0,0,newValue.width, newValue.height)
}
get{
return self.bounds.size
}
}
init(data contentData: NSData?, ofType uti: String?, desiredWidth:CGFloat = 320) {
self.width = desiredWidth
super.init(data: contentData, ofType: uti)
if let contentData = contentData {
let string = String(data: contentData, encoding: NSASCIIStringEncoding)!
let svgrender = SVGRenderer(string: self.fixSVGString(string))
let image = svgrender.asImageWithSize(CGSizeMake(self.width, 1000), andScale: UIScreen.mainScreen().scale)
self.image = image
self.size = image.size
}
}
override func attachmentBoundsForTextContainer(textContainer: NSTextContainer?, proposedLineFragment lineFrag: CGRect, glyphPosition position: CGPoint, characterIndex charIndex: Int) -> CGRect {
return CGRectInset(self.bounds, 0, 20)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func fixSVGString(string:String) -> String {
var result: String?
if string.hasPrefix("rtfd"){
let startIndex = string.rangeOfString("<?xml")?.startIndex
let stopIndex = string.rangeOfString("</svg>")?.endIndex
result = string.substringWithRange(startIndex! ..< stopIndex!)
} else {
result = string
}
return result!
}
}
它可以工作,但有一个缺陷:非 ASCII 字符被破坏。
最重要的是,HTML 和 SVG 都是 UTF-8 编码的,但在附件类中,我必须将 SVG 字符串实例化为 ASCII
let string = String(data: contentData, encoding: NSASCIIStringEncoding)!
否则它将为零。
fixSVGString(_:) 删除了一些已添加的富文本信息。
如何对 SVG 图像强制执行 UTF-8 编码?
【问题讨论】:
标签: ios swift cocoa-touch svg nsattributedstring