Vas*_*vev 6 uikit nsattributedstring uigraphicscontext swift
让我们想象一下我有一些文字:" 有些文字是梯形的. "
我有NSAttributedString扩展,它返回带有属性文本的UIImage:
extension NSAttributedString {
func asImage() -> UIImage? {
defer {
UIGraphicsEndImageContext()
}
let size = boundingRect(with: CGSize.zero, options: [.usesLineFragmentOrigin, .truncatesLastVisibleLine], context: nil).size
UIGraphicsBeginImageContext(size)
draw(at: CGPoint.zero)
return UIGraphicsGetImageFromCurrentImageContext()
}
}
Run Code Online (Sandbox Code Playgroud)
但是这个函数在一行中返回文本,因为使用boundingRect:
------------------------------------
|Some attributed text in trapezoid.|
------------------------------------
Run Code Online (Sandbox Code Playgroud)
如果我使用自定义rect来绘制文本,那将无济于事......
UIGraphicsBeginImageContext(CGRect(x: 0, y: 0, width: 100, height: 30))
draw(at: CGPoint.zero)
Run Code Online (Sandbox Code Playgroud)
...因为文字将是矩形:
--------------
|Some attribu|
|ted text in |
|trapezoid. |
--------------
Run Code Online (Sandbox Code Playgroud)
我需要的是在具有已知角位置(或具有已知半径的圆圈)的梯形中绘制文本.所以每个新的文本行都应该以一点偏移量开始,参见示例:

所以我希望看到类似的东西:
---------------
\Some attribut/
\ed text in /
\trapezoid/
---------
Run Code Online (Sandbox Code Playgroud)
我怎样才能达到这个效果?
您必须在此处下降到 CoreText 级别。好消息是,您将能够以您想要的任何形状绘制文本!
extension NSAttributedString {
public func draw(in path: CGPath) {
let context = UIGraphicsGetCurrentContext()!
let transform = CGAffineTransform(scaleX: +1, y: -1)
let flippedPath = CGMutablePath()
flippedPath.addPath(path, transform: transform)
let range = CFRange(location: 0, length: 0)
let framesetter = CTFramesetterCreateWithAttributedString(self)
let frame = CTFramesetterCreateFrame(framesetter, range, flippedPath, nil)
context.saveGState()
// Debug: fill path.
context.setFillColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 0.5)
context.beginPath()
context.addPath(path)
context.fillPath()
context.concatenate(transform)
CTFrameDraw(frame, context)
context.restoreGState()
}
}
Run Code Online (Sandbox Code Playgroud)
你可以像这样使用它:
let string = NSAttributedString(string: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit.")
let bounds = CGRect(x: 0, y: 0, width: 120, height: 120)
let path = CGMutablePath()
path.move(to: CGPoint(x: 10, y: 10))
path.addLine(to: CGPoint(x: 110, y: 10))
path.addLine(to: CGPoint(x: 90, y: 110))
path.addLine(to: CGPoint(x: 30, y: 110))
path.closeSubpath()
UIGraphicsBeginImageContextWithOptions(bounds.integral.size, true, 0)
defer { UIGraphicsEndImageContext() }
let context = UIGraphicsGetCurrentContext()!
context.setFillColor(UIColor.white.cgColor)
context.fill(.infinite)
string.draw(in: path)
let image = UIGraphicsGetImageFromCurrentImageContext()!
Run Code Online (Sandbox Code Playgroud)
坏消息是,这个解决方案最后并没有给你一个省略号。如果您确实想要这样,您可能需要对框架调节器给您的最后一行进行一些调整。
| 归档时间: |
|
| 查看次数: |
569 次 |
| 最近记录: |