可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm currently developing a simple photoshop like application on iphone. When I want to flatten my layers, the labels are at the good position but with a bad font size.
Here's my code to flatten :
UIGraphicsBeginImageContext(CGSizeMake(widthDocument,widthDocument));
for (UILabel *label in arrayLabel) {
[label drawTextInRect:label.frame];
}
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Anybody can help me ?
回答1:
From: pulling an UIImage from a UITextView or UILabel gives white image.
// iOS
- (UIImage *)grabImage {
// Create a "canvas" (image context) to draw in.
UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.opaque, 0.0); // high res
// Make the CALayer to draw in our "canvas".
[[self layer] renderInContext: UIGraphicsGetCurrentContext()];
// Fetch an UIImage of our "canvas".
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
// Stop the "canvas" from accepting any input.
UIGraphicsEndImageContext();
// Return the image.
return image;
}
// Swift extension w/ usage. credit @Heberti Almeida in below comments
extension UIImage {
class func imageWithLabel(label: UILabel) -> UIImage {
UIGraphicsBeginImageContextWithOptions(label.bounds.size, false, 0.0)
label.layer.renderInContext(UIGraphicsGetCurrentContext()!)
let img = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return img
}
}
The usage:
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 30, height: 22))
label.text = bulletString
let image = UIImage.imageWithLabel(label)
回答2:
I have created a Swift extension to render the UILabel
into a UIImage
:
extension UIImage {
class func imageWithLabel(label: UILabel) -> UIImage {
UIGraphicsBeginImageContextWithOptions(label.bounds.size, false, 0.0)
label.layer.renderInContext(UIGraphicsGetCurrentContext()!)
let img = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return img
}
}
EDIT: Improved Swift 4 version
extension UIImage {
class func imageWithLabel(_ label: UILabel) -> UIImage {
UIGraphicsBeginImageContextWithOptions(label.bounds.size, false, 0)
defer { UIGraphicsEndImageContext() }
label.layer.render(in: UIGraphicsGetCurrentContext()!)
return UIGraphicsGetImageFromCurrentImageContext() ?? UIImage()
}
}
The usage is simple:
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 30, height: 22))
label.text = bulletString
let image = UIImage.imageWithLabel(label)
回答3:
you need to render the label in a context
replace
[label drawTextInRect:label.frame];
with
[label.layer renderInContext:UIGraphicsGetCurrentContext()];
and you will need to create one image per label, so move the for loop to outside the begin and end context calls
回答4:
for Swift, I use this UIView-extension:
// Updated for Swift 3.0
extension UIView {
var grabbedImage:UIImage? {
get {
UIGraphicsBeginImageContextWithOptions(bounds.size, false, 0.0)
layer.render(in: UIGraphicsGetCurrentContext()!)
let img = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return img
}
}
}
回答5:
You can use renderInContext on any CALayer. It will draw your view's layer on the context. So that you can change it to an image. Also if you do renderInContext on a view , all its subviews will be drawn onto the context. So instead of iterating through all the labels, while adding the labels, you can add those to a containerView. And just need to do renderInContext on that containerView.
回答6:
extension UIImage {
class func imageFrom(text: String, width: CGFloat, font: UIFont, textAlignment: NSTextAlignment, lineBreakMode: NSLineBreakMode) -> UIImage? {
let label = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude))
label.text = text
label.font = font
label.textAlignment = textAlignment
label.lineBreakMode = lineBreakMode
label.sizeToFit()
UIGraphicsBeginImageContextWithOptions(label.bounds.size, false, 0.0)
label.layer.render(in: UIGraphicsGetCurrentContext()!)
let img = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return img
}
}
Using:
let iv = UIImageView(image: UIImage.imageFrom(text: "Test For \nYarik", width: 537.0, font: UIFont.systemFont(ofSize: 30), textAlignment: .center, lineBreakMode: .byWordWrapping))
iv.contentMode = .scaleAspectFit