我试图在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中)随后出现的相同数字增加。
这是图片供参考 -
我试图通过将NSAttributedString.Key.kern设置为0来解决问题,但是它没有改变行为。
我是否从计算中遗漏了X轴中的任何重要属性,因为我无法在每个数字上得到正确对齐的边界框?请建议。
您需要使用的关键功能是:
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。以下是剪切解决方案的示例: