让我们想象一下我有一些文字:“有些文字是梯形的.”
我有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() } }
但是这个函数在一行中返回文本,因为使用了boundingRect:
------------------------------------ |Some attributed text in trapezoid.| ------------------------------------
如果我使用自定义rect来绘制文本,那将无济于事……
UIGraphicsBeginImageContext(CGRect(x: 0,y: 0,width: 100,height: 30)) draw(at: CGPoint.zero)
…因为文字将是矩形:
-------------- |Some attribu| |ted text in | |trapezoid. | --------------
我需要的是在具有已知角位置(或具有已知半径的圆圈)的梯形中绘制文本.所以每个新的文本行都应该以一点偏移量开始,参见示例:
所以我希望看到类似的东西:
--------------- \Some attribut/ \ed text in / \trapezoid/ ---------
我怎样才能达到这个效果?
解决方法
你必须在这里下载到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() } }
你可以像这样使用它:
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,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()!
坏消息是,这个解决方案最后没有给你一个省略号.如果你真的想拥有它,你可能需要对framesetter给你的最后一行做一些调整.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。