在UITextField中输入的每个数字周围的绘图框

问题描述 投票:0回答:1

我试图在UITextField中为用户输入的每个数字绘制框,键盘类型为 - 数字键盘。

为了简化问题陈述,我假设每个数字(0到9)的字形都有相同的边界框,我使用下面的代码获得:

func getGlyphBoundingRect() -> CGRect? {
        guard let font = font else {
            return nil
        }
        // As of now taking 8 as base digit
        var unichars = [UniChar]("8".utf16)
        var glyphs = [CGGlyph](repeating: 0, count: unichars.count)
        let gotGlyphs = CTFontGetGlyphsForCharacters(font, &unichars, &glyphs, unichars.count)
        if gotGlyphs {
            let cgpath = CTFontCreatePathForGlyph(font, glyphs[0], nil)!
            let path = UIBezierPath(cgPath: cgpath)
            return path.cgPath.boundingBoxOfPath
        }
        return nil
    }

我正在使用以下代码绘制由此获得的每个边界框:

func configure() {
        guard let boundingRect = getGlyphBoundingRect() else {
            return
        }
        for i in 0..<length { // length denotes number of allowed digits in the box
            var box = boundingRect
            box.origin.x = (CGFloat(i) * boundingRect.width)
            let shapeLayer = CAShapeLayer()
            shapeLayer.frame = box
            shapeLayer.borderWidth = 1.0
            shapeLayer.borderColor = UIColor.orange.cgColor
            layer.addSublayer(shapeLayer)
        }
    }

现在的问题是 -

如果我在文本字段中输入数字 - 8,8,8,那么对于第一次出现的数字,绘制的边界框是对齐的,但是对于第二次出现的相同数字,边界框会出现一个偏移(通过负x),偏移值(在负x中)随后出现的相同数字增加。

这是图片供参考 -

enter image description here

我试图通过将NSAttributedString.Key.kern设置为0来解决问题,但是它没有改变行为。

我是否从计算中遗漏了X轴中的任何重要属性,因为我无法在每个数字上得到正确对齐的边界框?请建议。

swift uitextfield core-text
1个回答
0
投票

您需要使用的关键功能是:

protocol UITextInput {
   public func firstRect(for range: UITextRange) -> CGRect
}

以下是作为功能的解决方案:

extension UITextField {
   func characterRects() -> [CGRect] {
      var beginningOfRange = beginningOfDocument

      var characterRects = [CGRect]()

      while beginningOfRange != endOfDocument {
         guard let endOfRange = position(from: beginningOfRange, offset: 1), let textRange = textRange(from: beginningOfRange, to: endOfRange) else { break }

         beginningOfRange = endOfRange

         var characterRect = firstRect(for: textRange)

         characterRect = convert(characterRect, from: textInputView)

         characterRects.append(characterRect)
      }

      return characterRects
   }
}

请注意,如果文本字段的文本太长,则可能需要剪辑您的rects。以下是剪切解决方案的示例:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.