Ios 如何定义自定义NSUnderlineStyle

Ios 如何定义自定义NSUnderlineStyle,ios,swift,nsattributedstring,textkit,nslayoutmanager,Ios,Swift,Nsattributedstring,Textkit,Nslayoutmanager,查看NSLayoutManager的文档,特别是方法,我注意到以下几点(我的重点): underlineVal 要绘制的下划线样式。此值是从NSUnderlineStyleAttributeName的值派生的掩码-例如,(NSUnderlinePatternDash|NSUnderlineStyleThick)子类可以定义自定义下划线样式 我的问题是:这到底意味着什么 是一个枚举,不能扩展或重写。当然,您可以为属性提供一个随机的原始Int值,枚举案例中没有包括: self.addAttribut

查看
NSLayoutManager
的文档,特别是方法,我注意到以下几点(我的重点):

underlineVal

要绘制的下划线样式。此值是从
NSUnderlineStyleAttributeName
的值派生的掩码-例如,(
NSUnderlinePatternDash
|
NSUnderlineStyleThick
子类可以定义自定义下划线样式

我的问题是:这到底意味着什么

是一个枚举,不能扩展或重写。当然,您可以为属性提供一个随机的原始
Int
值,枚举案例中没有包括:

self.addAttribute(NSUnderlineStyleAttributeName,值:100022,范围:lastUpdatedWordRange)

这将向布局管理器传递一个“无效”但可用的
下划线类型

但这几乎让人感觉不到安全,而且绝对不雅观


我在网上找不到任何例子,在苹果的文档中也找不到关于这些神秘的自定义下划线样式的线索。我很想知道我是否遗漏了一些明显的东西。

我这里有一个示例项目,我用它在TextKit上进行了一次演讲,我不久前给出了它,它正是您想要的:

本例中的下划线是一条曲线:

该解决方案的核心是自定义NSLayoutManager:

let CustomUnderlineStyle = 0x11

class UnderlineLayoutManager: NSLayoutManager {

    func drawFancyUnderlineForRect(_ rect: CGRect) {
        let left = rect.minX
        let bottom = rect.maxY
        let width = rect.width

        let path = UIBezierPath()
        path.move(to: CGPoint(x: left, y: bottom))
        var x = left
        var y = bottom
        var i = 0
        while (x <= left + width) {
            path.addLine(to: CGPoint(x: x, y: y))
            x += 2
            if i % 2 == 0 {
                y = bottom + 2.0
            }
            else {
                y = bottom
            }
            i += 1;
        }

        path.stroke()
    }

    override func drawUnderline(forGlyphRange glyphRange: NSRange, underlineType underlineVal: NSUnderlineStyle, baselineOffset: CGFloat, lineFragmentRect lineRect: CGRect, lineFragmentGlyphRange lineGlyphRange: NSRange, containerOrigin: CGPoint) {

        if underlineVal.rawValue & CustomUnderlineStyle == CustomUnderlineStyle {

            let charRange = characterRange(forGlyphRange: glyphRange, actualGlyphRange: nil)
            if let underlineColor = textStorage?.attribute(NSUnderlineColorAttributeName, at: charRange.location, effectiveRange: nil) as? UIColor {
                underlineColor.setStroke()
            }

            if let container = textContainer(forGlyphAt: glyphRange.location, effectiveRange: nil) {
                let boundingRect = self.boundingRect(forGlyphRange: glyphRange, in: container)
                let offsetRect = boundingRect.offsetBy(dx: containerOrigin.x, dy: containerOrigin.y)

                drawFancyUnderlineForRect(offsetRect)
            }
        }
        else {
            super.drawUnderline(forGlyphRange: glyphRange, underlineType: underlineVal, baselineOffset: baselineOffset, lineFragmentRect: lineRect, lineFragmentGlyphRange: lineGlyphRange, containerOrigin: containerOrigin)
        }
    }
}
让CustomUnderlineStyle=0x11
类UnderlineLayoutManager:NSLayoutManager{
func drawFancyUnderlineForRect(rect:CGRect){
设left=rect.minX
让bottom=rect.maxY
let width=rect.width
let path=UIBezierPath()
移动路径(到:CGPoint(x:左,y:下))
var x=左
var y=底部
变量i=0

虽然(x NSUnderlineStyle似乎是一个糟糕的团队成员。它的文档记录很差,而且在Swift中,它仍然没有被转换为一个选项集。当读取给定样式的标志时,它似乎不可靠(或者我做错了)。我希望能帮上更多的忙,但我仍在研究解决方案。。。