在Swift 4中使用NSMutableParagraphStyle和段落SpacingBefore时,如何获得正确的插入符大小和位置

时间:2019-01-26 23:01:43

标签: ios swift nsattributedstring caret nsmutableattributedstring

我一直在UITextView中处理属性文本(Swift 4.2,并注意到,一旦我在设计中引入了“ paragraphSpacingBefore”,则插入符号在每个新段落的第一行都太大了。

我发现了对Stackoverflow的建议修复,似乎可以解决插入符号的大小问题。我发现的问题是,当插入行插入到新段落的开头时,插入符本身就浮在目标行上方。

UITextView lineSpacing make cursor height not same

Caret Floats above the target line

我尝试解决它,保持了原始解决方案的核心思想,并添加了一些偏移逻辑。在调试期间,我注意到,即使不需要时,插入符号大小的原始答案也总是会调整大小,因此我添加了方差过滤器(仅在方差> 10%时才进行调整)。这样做是因为我认为每次调整都会干扰我的生活。浮动的插入符号问题。

如果有人可以看看我提出的方法,提出改进或更好的方法等,我将不胜感激:

override func caretRect(for position: UITextPosition) -> CGRect {
    var superRect = super.caretRect(for: position)
    guard let isFont = self.font else {
        return superRect
    }
    let proposedHeight: CGFloat = isFont.pointSize - isFont.descender
    var delta: CGFloat = superRect.size.height - proposedHeight
    delta = (delta * delta).squareRoot()

    //If the delta is < 10% of the original height just return the original rect
    if delta / superRect.size.height < 0.1 {
        return superRect
    }

    superRect.size.height = isFont.pointSize - isFont.descender
    // "descender" is expressed as a negative value,
    // so to add its height you must subtract its value
    superRect.origin.y = superRect.origin.y + delta
    // delta is used to correct for resized caret floating above the target line

    return superRect
}

1 个答案:

答案 0 :(得分:0)

我有一个解决方案:

// Fix long cursor height when at the end of paragraph with paragraphspacing and wrong cursor position in titles with paragraph spacing before
override public func caretRect(for position: UITextPosition) -> CGRect {
    var superRect = super.caretRect(for: position)
    guard let isFont = self.font else { return superRect }

    let location = self.offset(from: self.beginningOfDocument, to: position)
    if let paragrahStyle = self.storage.attribute(.paragraphStyle, at: location, effectiveRange: nil) as? NSParagraphStyle {
        superRect.origin.y += paragrahStyle.paragraphSpacingBefore
    }

    superRect.size.height = isFont.pointSize - isFont.descender
    return superRect
}

真正的问题paragraphSpacingBefore。因此,您要做的就是获取段落样式属性,获取间距并将光标移动该间距。这适用于所有文本。