3

I am trying to find the position of a letter in a labelText . The code in Objective C is

NSRange range = [@"Good,Morning" rangeOfString:@","];
NSString *prefix = [@"Good,Morning" substringToIndex:range.location];
CGSize size = [prefix sizeWithFont:[UIFont systemFontOfSize:18]];
CGPoint p = CGPointMake(size.width, 0);
NSLog(@"p.x: %f",p.x);
NSLog(@"p.y: %f",p.y);

Please someone tell me how we write the above code in swift ? I am finding it bit difficult to calculate range of a string .

iPhoneDeveloper
  • 958
  • 1
  • 14
  • 23

4 Answers4

2

I finally would recommend following variant:

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)
    }
}

Client's code:

let str = "Good,Morning"
let p = str.characterPosition(",")
Igor B.
  • 2,219
  • 13
  • 17
1

A safe way to find range is to use if-let statement since rangeOfString may return a nil value. Go through the following code:

if let range = str.rangeOfString(",") {
    let prefix = str.substringToIndex(range.startIndex)
    let size: CGSize = prefix.sizeWithAttributes([NSFontAttributeName: UIFont.systemFontOfSize(14.0)])
    let p = CGPointMake(size.width, 0)
}

Above code gives the result as: enter image description here

Animesh Porwal
  • 557
  • 1
  • 10
  • 21
  • Thanks . I wont forget to use if-let . – iPhoneDeveloper May 27 '16 at 06:12
  • What is the difference between "range.startIndex" and "range.endIndex" ? I get the output as "Good" and "Good,"(with a comma). – iPhoneDeveloper May 27 '16 at 06:16
  • @user1512106 When you print the value of range in the above code using `print(range)`, you get the value as **4..<5**. Here `range.startIndex` is _4_ and `range.endIndex` is _5_. And you read it like **a range that runs from 4 to 5, but does not include 5**. You can find more information about range operators [here](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/BasicOperators.html#//apple_ref/doc/uid/TP40014097-CH6-ID73). – Animesh Porwal May 27 '16 at 16:41
1

Try this code::

let range : NSRange = "Good,Morning".rangeOfString(",");
let prefix: NSString = "Good,Morning".substringToIndex(range.location);
let size: CGSize = prefix.sizeWithAttributes([NSFontAttributeName: UIFont.systemFontOfSize(18.0)])
let p : CGPoint = CGPointMake(size.width, 0);
NSLog("p.x: %f",p.x)
NSLog("p.y: %f",p.y)

Swift 4

    let range: NSRange = ("Good,Morning" as NSString).range(of: ",")
    let prefix = ("Good,Morning" as NSString).substring(to: range.location)//"Good,Morning".substring(to: range.location)
    let size: CGSize = prefix.size(withAttributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 18.0)])
    let p = CGPoint(x: size.width , y: 0)
    print("p.x: \(p.x)")
    print("p.y: \(p.y)")
Bhadresh Kathiriya
  • 3,147
  • 2
  • 21
  • 41
0

Nothing really changes when converting this to swift just the syntax

var range: NSRange = "Good,Morning".rangeOfString(",")
var prefix: String = "Good,Morning".substringToIndex(range.location)
print(prefix) //Good
kye
  • 2,166
  • 3
  • 27
  • 41