如何将 NSMutableParagraphStyle 中的第一行加粗?
How do you bold the first line in an NSMutableParagraphStyle?
我有一个名为 "rectangle" 的 class 来制作自定义 UILabel。我在矩形 class 中覆盖了 "draw"。当我实例化标签时,我希望第一行文本以粗体显示。我知道如何通过手动获取每个字符串的范围来解决这个问题......但是,我有 300 多个字符串要做。这些字符串当前位于一个数组中,格式如下:"Happy \n Birthday"。我怎样才能把 "Happy" 这个词加粗?
var messageText = "Happy \n Birthday"
let rectanglePath = UIBezierPath(rect: rectangleRect)
context.saveGState()
UIColor.white.setFill()
rectanglePath.fill()
context.restoreGState()
darkPurple.setStroke()
rectanglePath.lineWidth = 0.5
rectanglePath.lineCapStyle = .square
rectanglePath.lineJoinStyle = .round
rectanglePath.stroke()
let rectangleStyle = NSMutableParagraphStyle()
rectangleStyle.alignment = .center
let rectangleFontAttributes = [
.font: UIFont.myCustomFont(true),
.foregroundColor: UIColor.black,
.paragraphStyle: rectangleStyle,
] as [NSAttributedString.Key: Any]
let rectangleTextHeight: CGFloat = messageText.boundingRect(with: CGSize(width: rectangleRect.width, height: CGFloat.infinity), options: .usesLineFragmentOrigin, attributes: rectangleFontAttributes, context: nil).height
context.saveGState()
context.clip(to: rectangleRect)
messageText.draw(in: CGRect(x: rectangleRect.minX, y: rectangleRect.minY + (rectangleRect.height - rectangleTextHeight) / 2, width: rectangleRect.width, height: rectangleTextHeight), withAttributes: rectangleFontAttributes)
context.restoreGState()
您可以通过 newline:
分隔字符串来找到第一个
let firstLine = "Happy \n Birthday".split(separator: "\n").first
这将为您提供字符串的第一行。 (长文本多行不算)然后你可以使用它找到范围并应用粗体效果。
这是如何工作的:
- 您需要按照接受多行的方式设置标签:
- 找到第一行的范围
- 转换为
nsRange
- 将属性应用于范围
这是一个完整的示例:
import UIKit
import PlaygroundSupport
extension StringProtocol where Index == String.Index {
func nsRange(from range: Range<Index>) -> NSRange {
return NSRange(range, in: self)
}
}
class MyViewController : UIViewController {
override func loadView() {
let view = UIView()
view.backgroundColor = .white
let label = UILabel()
label.numberOfLines = 0
label.text = "Happy \n Birthday"
label.textColor = .black
let text = "Happy \n Birthday"
let attributedString = NSMutableAttributedString(string: text)
let firstLine = text.split(separator: "\n").first!
let range = text.range(of: firstLine)!
attributedString.addAttributes([.font : UIFont.boldSystemFont(ofSize: 14)], range: text.nsRange(from: range))
label.attributedText = attributedString
label.sizeToFit()
view.addSubview(label)
self.view = view
}
}
PlaygroundPage.current.liveView = MyViewController()
我有一个名为 "rectangle" 的 class 来制作自定义 UILabel。我在矩形 class 中覆盖了 "draw"。当我实例化标签时,我希望第一行文本以粗体显示。我知道如何通过手动获取每个字符串的范围来解决这个问题......但是,我有 300 多个字符串要做。这些字符串当前位于一个数组中,格式如下:"Happy \n Birthday"。我怎样才能把 "Happy" 这个词加粗?
var messageText = "Happy \n Birthday"
let rectanglePath = UIBezierPath(rect: rectangleRect)
context.saveGState()
UIColor.white.setFill()
rectanglePath.fill()
context.restoreGState()
darkPurple.setStroke()
rectanglePath.lineWidth = 0.5
rectanglePath.lineCapStyle = .square
rectanglePath.lineJoinStyle = .round
rectanglePath.stroke()
let rectangleStyle = NSMutableParagraphStyle()
rectangleStyle.alignment = .center
let rectangleFontAttributes = [
.font: UIFont.myCustomFont(true),
.foregroundColor: UIColor.black,
.paragraphStyle: rectangleStyle,
] as [NSAttributedString.Key: Any]
let rectangleTextHeight: CGFloat = messageText.boundingRect(with: CGSize(width: rectangleRect.width, height: CGFloat.infinity), options: .usesLineFragmentOrigin, attributes: rectangleFontAttributes, context: nil).height
context.saveGState()
context.clip(to: rectangleRect)
messageText.draw(in: CGRect(x: rectangleRect.minX, y: rectangleRect.minY + (rectangleRect.height - rectangleTextHeight) / 2, width: rectangleRect.width, height: rectangleTextHeight), withAttributes: rectangleFontAttributes)
context.restoreGState()
您可以通过 newline:
分隔字符串来找到第一个let firstLine = "Happy \n Birthday".split(separator: "\n").first
这将为您提供字符串的第一行。 (长文本多行不算)然后你可以使用它找到范围并应用粗体效果。
这是如何工作的:
- 您需要按照接受多行的方式设置标签:
- 找到第一行的范围
- 转换为
nsRange
- 将属性应用于范围
这是一个完整的示例:
import UIKit
import PlaygroundSupport
extension StringProtocol where Index == String.Index {
func nsRange(from range: Range<Index>) -> NSRange {
return NSRange(range, in: self)
}
}
class MyViewController : UIViewController {
override func loadView() {
let view = UIView()
view.backgroundColor = .white
let label = UILabel()
label.numberOfLines = 0
label.text = "Happy \n Birthday"
label.textColor = .black
let text = "Happy \n Birthday"
let attributedString = NSMutableAttributedString(string: text)
let firstLine = text.split(separator: "\n").first!
let range = text.range(of: firstLine)!
attributedString.addAttributes([.font : UIFont.boldSystemFont(ofSize: 14)], range: text.nsRange(from: range))
label.attributedText = attributedString
label.sizeToFit()
view.addSubview(label)
self.view = view
}
}
PlaygroundPage.current.liveView = MyViewController()