1

I need to get the xy coordinate of a character in a String, but couldn't find any up to date answers. How can I achieve this? I found this article here: Swift : How do I find the position(x,y) of a letter in a UILabel? but .rangeOfString is not available anymore:

extension String {

func characterPosition(character: Character, withFont: UIFont = UIFont.systemFontOfSize(18.0)) -> CGPoint? {

    guard let range = self.rangeOfString(String(character)) else {
        print("\(character) is missed")
        return nil
    }

    let prefix = self.substringToIndex(range.startIndex) as NSString
    let size = prefix.sizeWithAttributes([NSFontAttributeName: withFont])

    return CGPointMake(size.width, 0)
}

Do you know how to get it to work again?

yoKurt
  • 327
  • 1
  • 3
  • 8
  • 1
    The method is still there, only now it's called `range(of:)`. This way to find the position of a single character is not very robust though. – Sulthan Dec 20 '20 at 18:46
  • Okay, what would be a more robust variant? If I used range(of:), I get 3 errors in the let prefix = ... line: Property 'startIndex' requires that 'String.Index.Stride' conform to 'SignedInteger'; Property 'startIndex' requires that 'String.Index' conform to 'Strideable'; Value of type 'String' has no member 'substringToIndex' – yoKurt Dec 20 '20 at 18:49

1 Answers1

1

Your Swift syntax is really old (Swift 2). Change range.startIndex to range.lowerBound. substringToIndex is now called substring(to: Index) but it is deprecated, you should use subscript self[..<range.lowerBound]. Btw there is no need to use String range(of: String) if you are looking for a index of a character. You can use collection method firstIndex(of: Element):

extension StringProtocol {
    func characterPosition(character: Character, with font: UIFont = .systemFont(ofSize: 18.0)) -> CGPoint? {
        guard let index = firstIndex(of: character) else {
            print("\(character) is missed")
            return nil
        }
        let string = String(self[..<index])
        let size = string.size(withAttributes: [.font: font])
        return CGPoint(x: size.width, y: 0)
    }
}
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
  • Do you also know how to get the distance between the first (or any other) baseline of a text in a UILabel and the top of the frame of the UILabel? – yoKurt Dec 21 '20 at 10:21