1

how can I check if a text in a UILabel went to a new line? I want to count the times when a text moved to a new line in order to get the distance between this line and the top of the UILabel. An easier way would be to get the number of the line which contains a certain word, but I couldn't find an answer for that. Do you know how to achieve it?

EDIT:

What I want to do is to add UITextFields into a label. I want the UITextFields to cover specific words, but the text in the label will change so the UITextField has to be dynamic. I already works, but only with the first line since in the UITextField, I can tap into the .firstBaselineAnchor property.

enter image description here

It works with this code here:

let labelView = UILabel(frame: .zero)
    labelView.translatesAutoresizingMaskIntoConstraints = false
    self.view.addSubview(labelView)
    NSLayoutConstraint.activate([
        labelView.leadingAnchor.constraint(equalTo: self.cardView.leadingAnchor, constant: 10),
        labelView.trailingAnchor.constraint(equalTo: self.cardView.trailingAnchor, constant: -10),
        labelView.topAnchor.constraint(equalTo: self.cardView.topAnchor, constant: 10)
    ])
    self.labelView = labelView
    let text = "This labelview ______ created to test how to replace the underscores with a textinput."
    labelView.text = text
    let font = UIFont.systemFont(ofSize: 30)
    labelView.font = font
    let distanceOfCharacterToStringStart = labelView.text?.characterPosition(character: "_", with: font)
    labelView.textAlignment = .left
    labelView.numberOfLines = 0
    // getCharacterAtPosition(of: text, with: font, in: labelView.frame.width)
    
    
    
    //MARK: - UITEXTFIELD
    
    let textField = UITextField(frame: .zero)
    textField.translatesAutoresizingMaskIntoConstraints = false
    self.view.addSubview(textField)
    NSLayoutConstraint.activate([
        textField.leadingAnchor.constraint(equalTo: labelView.leadingAnchor, constant: distanceOfCharacterToStringStart!.x - 0.5),
        textField.trailingAnchor.constraint(equalTo: labelView.trailingAnchor),
        textField.bottomAnchor.constraint(equalTo: labelView.firstBaselineAnchor, constant: 0 - labelView.font.descender),
        textField.heightAnchor.constraint(equalToConstant: labelView.font.lineHeight)
    ])
    self.labelView = labelView
    textField.backgroundColor = UIColor.red

(I know that I still have to fix the trailing constraint of the UITextView.) It calculates the distance between the beginning of the string and the first underscore character by using this method:

extension StringProtocol {
    func characterPosition(character: Character, with font: UIFont) -> 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)
    }
}

But now I want to get it to work for the other lines in between the first and last baseline as well. So I thought I would probably have to calculate where the text goes into the next line, and then I could substring it and again calculate the distance of the first character of the string in this line and the underscore in this line (if it exists) by using a similar method as shown above. Here is what I started creating in order to do so:

func getCharacterAtPosition(of string: String, with font: UIFont, in labelsize: CGFloat) -> [Character : Int] {
    
    var characterAtIndex: [Character : Int] = [:]
    var indexCount = 0
    
    for c in string {
        let upperBound = String.Index.init(utf16Offset: indexCount, in: string)
        let partOfFullString = String(string[..<upperBound])
        let size = partOfFullString.size(withAttributes: [.font: font])
        if size.width >= labelsize {
            characterAtIndex = [c : indexCount]
            indexCount = 0
            break
            
        } else {
            indexCount += 1
        }
    }
    return characterAtIndex
    
}

By counting the number of new lines and the distance of a character to the first character in each line, I could get the coordinates for my UITextView.

gcharita
  • 7,729
  • 3
  • 20
  • 37
yoKurt
  • 327
  • 1
  • 3
  • 8
  • This may help you https://stackoverflow.com/a/48795672/7009436 – Luca Sfragara Dec 21 '20 at 14:16
  • Thanks, but they seem to create a method to calculate the height of each line, which is not exactly what I am looking for I think (correct me if I am wrong and I could use it partially) – yoKurt Dec 22 '20 at 12:00
  • I am not sure, maybe you can divide the height of each line by the label height. Anyway, can you explain what you are trying to achieve by counting the lines in a label? There might be an easier approach. – Luca Sfragara Dec 22 '20 at 12:04
  • Yes sure, I will edit my answer to show you the whole thing. Just give me a few minutes. – yoKurt Dec 22 '20 at 12:20

0 Answers0