Swift图片添加文本:文本对齐、背景透明度及前置图片实现问题
Swift 图片添加文本的问题解决
以下是用于给图片添加文本的Swift代码:
for (index, textData) in textDataCurrentImg.enumerated() { let textColor = textData.fontColor let textFont = UIFont(name: textData.font.fontName, size: textData.fontSize)! let padding: CGFloat = 10.0 let breakdText = textData.addBreaks(in: textData.text, with: textFont, forWidth: newImage.size.width, padding: Int(textData.xPosition)) let scale = UIScreen.main.scale UIGraphicsBeginImageContextWithOptions(newImage.size, false, scale) // 绘制原图 newImage.draw(in: CGRect(origin: CGPoint.zero, size: newImage.size)) let textFontAttributes: [NSAttributedString.Key : Any] = [ NSAttributedString.Key.font: textFont, NSAttributedString.Key.foregroundColor: textColor, ] if let backColor = textData.backColor { // 绘制文本背景矩形 let textSize = breakdText.size(withAttributes: textFontAttributes) let backgroundRect = CGRect( origin: CGPoint(x: textData.xPosition - padding, y: textData.yPosition - padding), size: CGSize(width: textSize.width + 2 * padding, height: textSize.height + 2 * padding) ) backColor.setFill() UIRectFill(backgroundRect) } // 在背景上绘制文本 breakdText.draw(in: CGRect(x: textData.xPosition, y: textData.yPosition, width: newImage.size.width, height: newImage.size.height), withAttributes: textFontAttributes) newImage = UIGraphicsGetImageFromCurrentImageContext() ?? image UIGraphicsEndImageContext() }
实现过程中遇到三个问题,对应的解决方法如下:
1. 文本对齐不生效问题
尝试添加段落样式但未达到预期效果:
let textFontAttributes: [NSAttributedString.Key : Any] = [ NSAttributedString.Key.font: textFont, NSAttributedString.Key.foregroundColor: textColor, NSAttributedString.Key.paragraphStyle: { let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.alignment = textData.textAlignment return paragraphStyle }() ]
解决方法:
问题出在文本绘制的CGRect范围设置错误。draw(in:)会根据段落样式在指定rect内对齐文本,但原代码设置的width是整个图片宽度,导致对齐效果不明显。正确做法是根据文本实际尺寸和对齐方式调整绘制rect:
// 计算文本实际尺寸 let textSize = breakdText.size(withAttributes: textFontAttributes) var drawRect = CGRect(x: textData.xPosition, y: textData.yPosition, width: textSize.width, height: textSize.height) // 根据对齐方式调整x坐标 switch textData.textAlignment { case .right: drawRect.origin.x = newImage.size.width - textSize.width - textData.xPosition case .center: drawRect.origin.x = (newImage.size.width - textSize.width) / 2 case .left, .justified, .natural: break // 保持原有xPosition } // 绘制文本 breakdText.draw(in: drawRect, withAttributes: textFontAttributes)
同时确保addBreaks方法未强制修改文本换行逻辑,避免干扰段落样式的对齐效果。
2. 文本背景透明度实现
直接利用已有代码片段,替换原有背景色即可:
if let backColor = textData.backColor { let alpha: CGFloat = 0.5 let alphaColor = backColor.withAlphaComponent(alpha) let textSize = breakdText.size(withAttributes: textFontAttributes) let backgroundRect = CGRect( origin: CGPoint(x: textData.xPosition - padding, y: textData.yPosition - padding), size: CGSize(width: textSize.width + 2 * padding, height: textSize.height + 2 * padding) ) alphaColor.setFill() UIRectFill(backgroundRect) }
注意:已设置UIGraphicsBeginImageContextWithOptions(newImage.size, false, scale)(第二个参数为false,支持透明),因此透明背景可正常显示。
3. 文本前添加图片(当textData.isLocation为true时)
解决方法:
将图片作为NSTextAttachment嵌入富文本,实现图片与文本的一体化绘制,同时背景矩形自动包含图片区域:
// 构建带图片的富文本 var attributedText = NSMutableAttributedString(string: "") if textData.isLocation { // 加载位置图标(替换为你的图片资源) let locationImage = UIImage(named: "location_icon")! let attachment = NSTextAttachment() attachment.image = locationImage // 调整图片大小与文本基线对齐 let imageSize = CGSize(width: textFont.pointSize * 1.2, height: textFont.pointSize * 1.2) attachment.bounds = CGRect(origin: CGPoint(x: 0, y: (textFont.capHeight - imageSize.height)/2), size: imageSize) // 添加图片附件和空格分隔 attributedText.append(NSAttributedString(attachment: attachment)) attributedText.append(NSAttributedString(string: " ")) } // 添加原文本 attributedText.append(NSAttributedString(string: breakdText, attributes: textFontAttributes)) // 计算包含图片的富文本尺寸 let fullTextSize = attributedText.boundingRect(with: CGSize(width: newImage.size.width - textData.xPosition*2, height: CGFloat.greatestFiniteMagnitude), options: .usesLineFragmentOrigin, context: nil).size // 绘制背景(如果需要) if let backColor = textData.backColor { let alpha: CGFloat = 0.5 let alphaColor = backColor.withAlphaComponent(alpha) let backgroundRect = CGRect( origin: CGPoint(x: textData.xPosition - padding, y: textData.yPosition - padding), size: CGSize(width: fullTextSize.width + 2 * padding, height: fullTextSize.height + 2 * padding) ) alphaColor.setFill() UIRectFill(backgroundRect) } // 绘制富文本 attributedText.draw(in: CGRect(x: textData.xPosition, y: textData.yPosition, width: fullTextSize.width, height: fullTextSize.height))
此方式可让图片与文本保持基线对齐,背景矩形自动适配图片和文本的整体区域,无需手动调整位置。
内容的提问来源于stack exchange,提问作者Dhruvisha Joshi
相关产品推荐
相关产品推荐

