NSAttributedString:使图像适合容器
NSAttributedString: Fit image to container
我有一个由 HTML 生成的 NSAttributedString,它显示一些图像。问题是图像比容器大,我想知道如何将它们放入其中。
感谢您的帮助
我终于找到了该怎么做:
content.enumerateAttribute(NSAttachmentAttributeName, inRange: NSMakeRange(0, content.length), options: NSAttributedStringEnumerationOptions(0)) { (value, range, stop) -> Void in
if let attachement = value as? NSTextAttachment {
let image = attachement.imageForBounds(attachement.bounds, textContainer: NSTextContainer(), characterIndex: range.location)
let screenSize: CGRect = UIScreen.mainScreen().bounds
if image.size.width > screenSize.width-2 {
let newImage = image.resizeImage((screenSize.width-2)/image.size.width)
let newAttribut = NSTextAttachment()
newAttribut.image = newImage
content.addAttribute(NSAttachmentAttributeName, value: newAttribut, range: range)
}
}
}
函数resizeImage()
定义如下:
extension UIImage {
func resizeImage(scale: CGFloat) -> UIImage {
let newSize = CGSizeMake(self.size.width*scale, self.size.height*scale)
let rect = CGRectMake(0, 0, newSize.width, newSize.height)
UIGraphicsBeginImageContext(newSize)
self.drawInRect(rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
}
Swift 3 版本
text.enumerateAttribute(NSAttachmentAttributeName, in: NSMakeRange(0, text.length), options: .init(rawValue: 0), using: { (value, range, stop) in
if let attachement = value as? NSTextAttachment {
let image = attachement.image(forBounds: attachement.bounds, textContainer: NSTextContainer(), characterIndex: range.location)!
let screenSize: CGRect = UIScreen.main.bounds
if image.size.width > screenSize.width-20 {
let newImage = image.resizeImage(scale: (screenSize.width-2)/image.size.width)
let newAttribut = NSTextAttachment()
newAttribut.image = newImage
text.addAttribute(NSAttachmentAttributeName, value: newAttribut, range: range)
}
}
})
函数resizeImage()
定义如下:
func resizeImage(scale: CGFloat) -> UIImage {
let newSize = CGSize(width: self.size.width*scale, height: self.size.height*scale)
let rect = CGRect(origin: CGPoint.zero, size: newSize)
UIGraphicsBeginImageContext(newSize)
self.draw(in: rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
Swift 4 版本 + 扩展和可自定义的图像最大宽度
extension NSAttributedString {
func attributedStringWithResizedImages(with maxWidth: CGFloat) -> NSAttributedString {
let text = NSMutableAttributedString(attributedString: self)
text.enumerateAttribute(NSAttributedStringKey.attachment, in: NSMakeRange(0, text.length), options: .init(rawValue: 0), using: { (value, range, stop) in
if let attachement = value as? NSTextAttachment {
let image = attachement.image(forBounds: attachement.bounds, textContainer: NSTextContainer(), characterIndex: range.location)!
if image.size.width > maxWidth {
let newImage = image.resizeImage(scale: maxWidth/image.size.width)
let newAttribut = NSTextAttachment()
newAttribut.image = newImage
text.addAttribute(NSAttributedStringKey.attachment, value: newAttribut, range: range)
}
}
})
return text
}
}
extension UIImage {
func resizeImage(scale: CGFloat) -> UIImage {
let newSize = CGSize(width: self.size.width*scale, height: self.size.height*scale)
let rect = CGRect(origin: CGPoint.zero, size: newSize)
UIGraphicsBeginImageContext(newSize)
self.draw(in: rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
}
您还可以将字符串包装在完整的 HTML 文档中,并使用 CSS
调整图像大小。
Swift 4.2
: 使用@Nic Hubbard 的方法
let htmlString = "Put Your YourHTML String Here"
let setHeightUsingCSS = "<head><style type=\"text/css\"> img{ max-height: 100%; max-width: \(self.textView.frame.size.width) !important; width: auto; height: auto;} </style> </head><body> \(htmlString) </body>"
self.textView.attributedText = setHeightUsingCSS.html2AttributedString
extension Data {
var html2AttributedString: NSAttributedString? {
do {
return try NSAttributedString(data: self, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)
} catch {
print("error:", error)
return nil
}
}
var html2String: String {
return html2AttributedString?.string ?? ""
}
}
extension String {
var html2AttributedString: NSAttributedString? {
return Data(utf8).html2AttributedString
}
var html2String: String {
return html2AttributedString?.string ?? ""
}
}
我有一个由 HTML 生成的 NSAttributedString,它显示一些图像。问题是图像比容器大,我想知道如何将它们放入其中。
感谢您的帮助
我终于找到了该怎么做:
content.enumerateAttribute(NSAttachmentAttributeName, inRange: NSMakeRange(0, content.length), options: NSAttributedStringEnumerationOptions(0)) { (value, range, stop) -> Void in
if let attachement = value as? NSTextAttachment {
let image = attachement.imageForBounds(attachement.bounds, textContainer: NSTextContainer(), characterIndex: range.location)
let screenSize: CGRect = UIScreen.mainScreen().bounds
if image.size.width > screenSize.width-2 {
let newImage = image.resizeImage((screenSize.width-2)/image.size.width)
let newAttribut = NSTextAttachment()
newAttribut.image = newImage
content.addAttribute(NSAttachmentAttributeName, value: newAttribut, range: range)
}
}
}
函数resizeImage()
定义如下:
extension UIImage {
func resizeImage(scale: CGFloat) -> UIImage {
let newSize = CGSizeMake(self.size.width*scale, self.size.height*scale)
let rect = CGRectMake(0, 0, newSize.width, newSize.height)
UIGraphicsBeginImageContext(newSize)
self.drawInRect(rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
}
Swift 3 版本
text.enumerateAttribute(NSAttachmentAttributeName, in: NSMakeRange(0, text.length), options: .init(rawValue: 0), using: { (value, range, stop) in
if let attachement = value as? NSTextAttachment {
let image = attachement.image(forBounds: attachement.bounds, textContainer: NSTextContainer(), characterIndex: range.location)!
let screenSize: CGRect = UIScreen.main.bounds
if image.size.width > screenSize.width-20 {
let newImage = image.resizeImage(scale: (screenSize.width-2)/image.size.width)
let newAttribut = NSTextAttachment()
newAttribut.image = newImage
text.addAttribute(NSAttachmentAttributeName, value: newAttribut, range: range)
}
}
})
函数resizeImage()
定义如下:
func resizeImage(scale: CGFloat) -> UIImage {
let newSize = CGSize(width: self.size.width*scale, height: self.size.height*scale)
let rect = CGRect(origin: CGPoint.zero, size: newSize)
UIGraphicsBeginImageContext(newSize)
self.draw(in: rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
Swift 4 版本 + 扩展和可自定义的图像最大宽度
extension NSAttributedString {
func attributedStringWithResizedImages(with maxWidth: CGFloat) -> NSAttributedString {
let text = NSMutableAttributedString(attributedString: self)
text.enumerateAttribute(NSAttributedStringKey.attachment, in: NSMakeRange(0, text.length), options: .init(rawValue: 0), using: { (value, range, stop) in
if let attachement = value as? NSTextAttachment {
let image = attachement.image(forBounds: attachement.bounds, textContainer: NSTextContainer(), characterIndex: range.location)!
if image.size.width > maxWidth {
let newImage = image.resizeImage(scale: maxWidth/image.size.width)
let newAttribut = NSTextAttachment()
newAttribut.image = newImage
text.addAttribute(NSAttributedStringKey.attachment, value: newAttribut, range: range)
}
}
})
return text
}
}
extension UIImage {
func resizeImage(scale: CGFloat) -> UIImage {
let newSize = CGSize(width: self.size.width*scale, height: self.size.height*scale)
let rect = CGRect(origin: CGPoint.zero, size: newSize)
UIGraphicsBeginImageContext(newSize)
self.draw(in: rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
}
您还可以将字符串包装在完整的 HTML 文档中,并使用 CSS
调整图像大小。
Swift 4.2 : 使用@Nic Hubbard 的方法
let htmlString = "Put Your YourHTML String Here"
let setHeightUsingCSS = "<head><style type=\"text/css\"> img{ max-height: 100%; max-width: \(self.textView.frame.size.width) !important; width: auto; height: auto;} </style> </head><body> \(htmlString) </body>"
self.textView.attributedText = setHeightUsingCSS.html2AttributedString
extension Data {
var html2AttributedString: NSAttributedString? {
do {
return try NSAttributedString(data: self, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)
} catch {
print("error:", error)
return nil
}
}
var html2String: String {
return html2AttributedString?.string ?? ""
}
}
extension String {
var html2AttributedString: NSAttributedString? {
return Data(utf8).html2AttributedString
}
var html2String: String {
return html2AttributedString?.string ?? ""
}
}