Рисование рамок вокруг каждой цифры для ввода в UITextField - PullRequest
0 голосов
/ 09 февраля 2019

Я пытаюсь нарисовать рамки вокруг каждой цифры, введенной пользователем в 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 голосов
/ 14 февраля 2019

Ключевая функция, которую вам нужно использовать:

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

...