iPhone - How to draw text in the middle of a rect
Swift 5
static func draw(_ text: String, _ rect: CGRect, _ font: UIFont) {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
let attributes = [
NSAttributedString.Key.paragraphStyle: paragraphStyle,
NSAttributedString.Key.font: font,
NSAttributedString.Key.foregroundColor: UIColor.red
]
NSAttributedString(string: text, attributes: attributes).draw(in: rect.insetBy(dx: 0, dy: (rect.height - font.pointSize)/2))
}
If you want to draw multiple lines,
func drawMutipleLine(text: String = "Good morning how \nare you , fine, thank\nyou good day. uck wood?",
_ rect: CGRect,
font: UIFont = UIFont(name: "HelveticaNeue-Thin", size: 15)!) -> UIImage {
let renderer = UIGraphicsImageRenderer(size: rect.size)
let image = renderer.image { ctx in
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
let font = UIFont(name: "HelveticaNeue-Thin", size: 15)!
let attributes = [NSAttributedString.Key.font:font, NSAttributedString.Key.paragraphStyle: paragraphStyle]
let numLines = text.split(separator: "\n").count + 1
NSAttributedString(string: text, attributes: attributes).draw(in: rect.insetBy(dx: 0, dy: (rect.height - font.pointSize * CGFloat(numLines))/2))
}
return image
}
Well, the font property pointSize
corresponds directly to the height in pixels of a NSString
drawn in that UIFont
, so your formula would be something like this:
- (void) drawString: (NSString*) s
withFont: (UIFont*) font
inRect: (CGRect) contextRect {
CGFloat fontHeight = font.pointSize;
CGFloat yOffset = (contextRect.size.height - fontHeight) / 2.0;
CGRect textRect = CGRectMake(0, yOffset, contextRect.size.width, fontHeight);
[s drawInRect: textRect
withFont: font
lineBreakMode: UILineBreakModeClip
alignment: UITextAlignmentCenter];
}
UITextAlignmentCenter
handles the horizontal
centering, so we use the full width of the contextRect. The lineBreakMode
can be whatever you like.
Here's an updated version for iOS7.0+.
I've also improved on the above answer by using the sizeWithAttributes:
method which returns the bounds of the text enabling you to properly position the text before drawing it. This removes the need to hardcode any adjustments which will break if you use a different size font or if you use a different font.
- (void) drawString: (NSString*) s
withFont: (UIFont*) font
inRect: (CGRect) contextRect {
/// Make a copy of the default paragraph style
NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
/// Set line break mode
paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail;
/// Set text alignment
paragraphStyle.alignment = NSTextAlignmentCenter;
NSDictionary *attributes = @{ NSFontAttributeName: font,
NSForegroundColorAttributeName: [UIColor whiteColor],
NSParagraphStyleAttributeName: paragraphStyle };
CGSize size = [s sizeWithAttributes:attributes];
CGRect textRect = CGRectMake(contextRect.origin.x + floorf((contextRect.size.width - size.width) / 2),
contextRect.origin.y + floorf((contextRect.size.height - size.height) / 2),
size.width,
size.height);
[s drawInRect:textRect withAttributes:attributes];
}