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

时间:2019-02-09 20:40:26

标签: swift uitextfield core-text

我正在尝试在用户在键盘类型为-数字键盘的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轴上的任何重要属性,因为我无法在每个数字上正确对齐边界框?请提出建议。

1 个答案:

答案 0 :(得分: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
   }
}

请注意,如果您输入的文字对于文本字段而言过长,则可能需要裁剪矩形。这是解决剪裁的示例:

enter image description here