【问题标题】:Using selectionRects(for:) with UITextField subclass将 selectionRects(for:) 与 UITextField 子类一起使用
【发布时间】:2020-01-27 09:42:06
【问题描述】:

我有一个UITextField 子类,我在其中覆盖左视图、文本和插入符号的绘图矩形。这是使用leftViewRect(forBounds:)leftViewRect(forBounds:)caretRect(for:) 等完成的。一切都按预期工作。

问题在于,因为我在caretRect(for:) 中将绘图矩形(向上)移动了-2 个点,所以所选文本的绘图矩形比它应该的低2 个点。我尝试覆盖selectionRects(for:),但UITextSelectionRectrect 是一个只能获取的属性。实现这一目标的正确方法是什么?

代码

public override func selectionRects(for range: UITextRange) -> [UITextSelectionRect] {
    super.selectionRects(for: range).map {
        var selectionRect = $0
        selectionRect.rect.origin.y -= 2 // Left side of mutating operator isn't mutable: 'rect' is a get-only property
        return selectionRect
    }
}

【问题讨论】:

  • 来自UITextSelectionRect 的文档:如果您正在实现自定义文本输入视图,您可以继承并使用您的自定义类来返回与选择相关的信息。子类化时,您应该覆盖并重新实现所有属性。在您的自定义实现中,不要调用 super..
  • 谢谢,我看到了。我仍然不确定如何确切地得到我想要的。我会使用来自super.selectionRects(for: range) 的映射值初始化UITextSelectionRect 子类,其中rect 属性的y 值被修改?一些示例代码会很有帮助。
  • 这似乎是你需要的。

标签: swift uitextfield uikit selection


【解决方案1】:

根据 rmaddy 的评论和 this answer,我通过子类化 UITextSelectionRect 并使用修改后的 rect 传入来自 super.selectionRects(for: range) 的映射值来解决这个问题。这是我登陆的:

public final class MyUITextField: UITextField {
    public override func selectionRects(for range: UITextRange) -> [UITextSelectionRect] {
        super.selectionRects(for: range).map {
            MyTextSelectionRect(
                rect: CGRect(x: $0.rect.origin.x, y: $0.rect.origin.y - 2, width: $0.rect.width, height: $0.rect.height),
                writingDirection: $0.writingDirection,
                containsStart: $0.containsStart,
                containsEnd: $0.containsEnd,
                isVertical: $0.isVertical
            )
        }
    }

    //...
}
public final class MyTextSelectionRect: UITextSelectionRect {
    public override var rect: CGRect { _rect }
    public override var writingDirection: NSWritingDirection { _writingDirection }
    public override var containsStart: Bool { _containsStart }
    public override var containsEnd: Bool { _containsEnd }
    public override var isVertical: Bool { _isVertical }

    private let _rect: CGRect
    private let _writingDirection: NSWritingDirection
    private let _containsStart: Bool
    private let _containsEnd: Bool
    private let _isVertical: Bool

    public init(
        rect: CGRect,
        writingDirection: NSWritingDirection,
        containsStart: Bool,
        containsEnd: Bool,
        isVertical: Bool
    ) {
        _rect = rect
        _writingDirection = writingDirection
        _containsStart = containsStart
        _containsEnd = containsEnd
        _isVertical = isVertical
    }
}

【讨论】:

    猜你喜欢
    • 2010-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多