加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

swift – 如何在梯形(或圆形)中绘制文本?

发布时间:2020-12-14 05:01:01 所属栏目:百科 来源:网络整理
导读:让我们想象一下我有一些文字:“有些文字是梯形的.” 我有NSAttributedString扩展,它返回带有属性文本的UIImage: extension NSAttributedString { func asImage() - UIImage? { defer { UIGraphicsEndImageContext() } let size = boundingRect(with: CGSiz
让我们想象一下我有一些文字:“有些文字是梯形的.”

我有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.  |
--------------

我需要的是在具有已知角位置(或具有已知半径的圆圈)的梯形中绘制文本.所以每个新的文本行都应该以一点偏移量开始,参见示例:

enter image description here

所以我希望看到类似的东西:

---------------
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给你的最后一行做一些调整.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读