В Swift 5 и iOS 12 вы можете выбрать один из следующих способов: 6 , чтобы решить вашу проблему.
# 1. Используя NSString
draw(at:withAttributes:)
метод
В простейшем случае, когда вы хотите преобразовать String
в UIImage
с некоторыми атрибутами, вы можете использовать draw(at:withAttributes:)
. Следующие коды игровой площадки показывают, как получить UIImage
из String
, используя draw(at:withAttributes:)
:
import UIKit
import PlaygroundSupport
let text = "Hello, world"
let attributes = [
NSAttributedString.Key.foregroundColor: UIColor.yellow,
NSAttributedString.Key.font: UIFont.systemFont(ofSize: 22)
]
let textSize = text.size(withAttributes: attributes)
UIGraphicsBeginImageContextWithOptions(textSize, true, 0)
text.draw(at: CGPoint.zero, withAttributes: attributes)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
PlaygroundPage.current.liveView = UIImageView(image: image)
import UIKit
import PlaygroundSupport
let text = "Hello, world"
let attributes = [
NSAttributedString.Key.foregroundColor: UIColor.yellow,
NSAttributedString.Key.font: UIFont.systemFont(ofSize: 22)
]
let textSize = text.size(withAttributes: attributes)
let renderer = UIGraphicsImageRenderer(size: textSize)
let image = renderer.image(actions: { context in
text.draw(at: CGPoint.zero, withAttributes: attributes)
})
PlaygroundPage.current.liveView = UIImageView(image: image)
Обратите внимание, что NSAttributedString
имеет аналогичный метод, называемый draw(at:)
.
# 2. Используя NSString
s draw(in:withAttributes:)
метод
В качестве альтернативы draw(at:withAttributes:)
вы можете использовать draw(in:withAttributes:)
.
import UIKit
import PlaygroundSupport
let text = "Hello, world"
let attributes = [
NSAttributedString.Key.foregroundColor: UIColor.yellow,
NSAttributedString.Key.font: UIFont.systemFont(ofSize: 22)
]
let textSize = text.size(withAttributes: attributes)
UIGraphicsBeginImageContextWithOptions(textSize, true, 0)
let rect = CGRect(origin: .zero, size: textSize)
text.draw(in: rect, withAttributes: attributes)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
PlaygroundPage.current.liveView = UIImageView(image: image)
import UIKit
import PlaygroundSupport
let text = "Hello, world"
let attributes = [
NSAttributedString.Key.foregroundColor: UIColor.yellow,
NSAttributedString.Key.font: UIFont.systemFont(ofSize: 22)
]
let textSize = text.size(withAttributes: attributes)
let renderer = UIGraphicsImageRenderer(size: textSize)
let image = renderer.image(actions: { context in
let rect = CGRect(origin: .zero, size: textSize)
text.draw(in: rect, withAttributes: attributes)
})
PlaygroundPage.current.liveView = UIImageView(image: image)
Обратите внимание, что NSAttributedString
имеет аналогичный метод, называемый draw(in:)
.
# 3. Используя NSString
draw(with:options:attributes:context:)
метод
В качестве альтернативы draw(at:withAttributes:)
и draw(in:)
вы можете использовать draw(with:options:attributes:context:)
. Обратите внимание, что у Apple есть некоторые рекомендации для draw(with:options:attributes:context:)
:
Этот метод использует базовый источник по умолчанию.
Если usesLineFragmentOrigin
не указано, высота прямоугольника будет игнорироваться, и операция считается однострочным.
import UIKit
import PlaygroundSupport
let text = "Hello, world"
let attributes = [
NSAttributedString.Key.foregroundColor: UIColor.yellow,
NSAttributedString.Key.font: UIFont.systemFont(ofSize: 22)
]
let textSize = text.size(withAttributes: attributes)
UIGraphicsBeginImageContextWithOptions(textSize, true, 0)
let rect = CGRect(origin: .zero, size: textSize)
text.draw(with: rect, options: [.usesLineFragmentOrigin], attributes: attributes, context: nil)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
PlaygroundPage.current.liveView = UIImageView(image: image)
import UIKit
import PlaygroundSupport
let text = "Hello, world"
let attributes = [
NSAttributedString.Key.foregroundColor: UIColor.yellow,
NSAttributedString.Key.font: UIFont.systemFont(ofSize: 22)
]
let textSize = text.size(withAttributes: attributes)
let renderer = UIGraphicsImageRenderer(size: textSize)
let image = renderer.image(actions: { context in
text.draw(with: .zero, options: [.usesLineFragmentOrigin], attributes: attributes, context: nil)
})
PlaygroundPage.current.liveView = UIImageView(image: image)
Обратите внимание, что NSAttributedString
имеет аналогичный метод, называемый draw(with:options:context:)
.
# 4. Используя CALayer
s render(in:)
метод
Если вы хотите захватить текст от UILabel
, UITextField
или UITextView
до UIImage
, вы можете использовать render(in:)
. Следующие коды Playground показывают, как сделать снимок текста содержимого UILabel
, используя render(in:)
:
import UIKit
import PlaygroundSupport
let label = UILabel(frame: .zero)
label.textColor = .yellow
label.font = UIFont.systemFont(ofSize: 22)
label.text = "Hello, world"
label.sizeToFit()
UIGraphicsBeginImageContextWithOptions(label.frame.size, true, 0)
guard let context = UIGraphicsGetCurrentContext() else { exit(0) }
label.layer.render(in: context)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
PlaygroundPage.current.liveView = UIImageView(image: image)
import UIKit
import PlaygroundSupport
let label = UILabel(frame: .zero)
label.textColor = .yellow
label.font = UIFont.systemFont(ofSize: 22)
label.text = "Hello, world"
label.sizeToFit()
let renderer = UIGraphicsImageRenderer(size: label.frame.size)
let image = renderer.image(actions: { context in
label.layer.render(in: context.cgContext)
})
PlaygroundPage.current.liveView = UIImageView(image: image)
# 5. Используя UIView
drawHierarchy(in:afterScreenUpdates:)
метод
Если вы хотите захватить текст от UILabel
, UITextField
или UITextView
до UIImage
, вы можете использовать drawHierarchy(in:afterScreenUpdates:)
. Обратите внимание, что у Apple есть некоторые рекомендации для drawHierarchy(in:afterScreenUpdates:)
:
Используйте этот метод, если вы хотите применить графический снимок, например размытие, к снимку вида. Этот метод не так быстр, как метод snapshotView(afterScreenUpdates:)
.
import UIKit
import PlaygroundSupport
let label = UILabel(frame: .zero)
label.textColor = .yellow
label.font = UIFont.systemFont(ofSize: 22)
label.text = "Hello, world"
label.sizeToFit()
UIGraphicsBeginImageContextWithOptions(label.frame.size, true, 0)
_ = label.drawHierarchy(in: label.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
PlaygroundPage.current.liveView = UIImageView(image: image)
import UIKit
import PlaygroundSupport
let label = UILabel(frame: .zero)
label.textColor = .yellow
label.font = UIFont.systemFont(ofSize: 22)
label.text = "Hello, world"
label.sizeToFit()
let renderer = UIGraphicsImageRenderer(size: label.frame.size)
let image = renderer.image(actions: { context in
_ = label.drawHierarchy(in: label.bounds, afterScreenUpdates: true)
})
PlaygroundPage.current.liveView = UIImageView(image: image)
# 6. Используя UIView
snapshotView(afterScreenUpdates:)
метод
Если вы можете получить UIView
вместо UIImage
из вашей операции моментального снимка, вы можете использовать snapshotView(afterScreenUpdates:)
. Следующий код Playground показывает, как сделать снимок текста содержимого UILabel
в UIView
, используя snapshotView(afterScreenUpdates:)
:
import UIKit
import PlaygroundSupport
let label = UILabel(frame: .zero)
label.textColor = .yellow
label.font = UIFont.systemFont(ofSize: 22)
label.text = "Hello, world"
label.sizeToFit()
let view = label.snapshotView(afterScreenUpdates: true)
PlaygroundPage.current.liveView = view