web-dev-qa-db-fra.com

Impossible de convertir la valeur de type 'Range <String.Index>' (ou 'Range <String.CharacterView.Index>') en type d'argument attendu 'NSRange' (ou '_NSRange')

J'essaie de remplacer une sous-chaîne avec l'attribut String. Voici mon code.

let searchText = self.searchBar.text!
let name = item.firstName ?? ""
let idNo = "Employee Id. \(item.employeeId ?? "NA")"

if let range = name.range(of: searchText, options: String.CompareOptions.caseInsensitive, range: nil, locale: nil)
{
    let attributedSubString = NSAttributedString.init(string: name.substring(with: range), attributes: [NSFontAttributeName : UIFont.boldSystemFont(ofSize: 17)])
    let normalNameString = NSMutableAttributedString.init(string: name)
    normalNameString.mutableString.replacingCharacters(in: range, with: attributedSubString)
    cell.name.attributedText = normalNameString
}
else
{
    cell.name.text = name
}

Je reçois une erreur de compilation

"Impossible de convertir la valeur de type 'Range' (ou 'Range') en un type d'argument attendu 'NSRange' (ou '_NSRange')". 

Que devrais-je changer ici?

6
Bharath Reddy

Vous pouvez utiliser NSString et NSRange. Vous devez également modifier cette ligne normalNameString.mutableString.replacingCharacters(in: range, with: attributedSubString) et utiliser celle-ci à la place normalNameString.replaceCharacters(in: nsRange, with: attributedSubString) car mutableString est NSMutableString et replacingCharacters expect String et non NSAttributtedString

Code complet

    let nsRange = NSString(string: name).range(of: searchText, options: String.CompareOptions.caseInsensitive)

    if nsRange.location != NSNotFound
    {
        let attributedSubString = NSAttributedString.init(string: NSString(string: name).substring(with: nsRange), attributes: [NSFontAttributeName : UIFont.boldSystemFont(ofSize: 17)])
        let normalNameString = NSMutableAttributedString.init(string: name)
        normalNameString.replaceCharacters(in: nsRange, with: attributedSubString)
        cell.name.attributedText = normalNameString
    }
    else
    {
        cell.name.text = name
    }
8
Reinier Melian

Vous devez créer une instance NSRange en utilisant les valeurs de position Range<String.index>lowerBound et UpperBound comme ci-dessous. 

let searchText = "Kiran"
let name = "Kiran Jasvanee"
let idNo = "Employee Id. \("24")"

if let range = name.range(of: searchText, options: String.CompareOptions.caseInsensitive, range: nil, locale: nil)
{
    let attributedSubString = NSAttributedString.init(string: name.substring(with: range), attributes: [NSFontAttributeName : UIFont.boldSystemFont(ofSize: 17)])
    let normalNameString = NSMutableAttributedString.init(string: name)

    let startPos = name.distance(from: searchText.characters.startIndex, to: range.lowerBound)
    let nsrange = NSMakeRange(startPos, searchText.characters.count)

    normalNameString.replaceCharacters(in: nsrange, with: attributedSubString)
    labelName.attributedText = normalNameString
}
else
{
    labelName.text = name
}  

add, self.searchBar.text! au lieu de "Kiran" dans searchtext constantet
ajoutez item.firstName ?? "" au lieu de "Kiran Jasvanee" dans name constant selon vos besoins.

Je l'ai essayé dans une démo, et le code que j'ai posté fonctionne très bien comme ci-dessous. Vérifiez s'il vous plaît.
 enter image description here

Si name = "AKiranJasvanee"
 enter image description here
Si name = "KiranJasvanee"
 enter image description here

2
Kiran Jasvanee

S'il te plaît, fais comme ça,

Premier,

extension String {

    func nsRange(from range: Range<String.Index>) -> NSRange {
        let from = range.lowerBound.samePosition(in: utf16)
        let to = range.upperBound.samePosition(in: utf16)
        return NSRange(location: utf16.distance(from: utf16.startIndex, to: from),
                       length: utf16.distance(from: from, to: to))
    }
}

après cela vous avez une étiquette et une ficelle comme ça

private func setAttributedLabel() {

    let lableText = UILabel()

    let strTitle = "Basic string Double tap" // your main string
    let title:NSMutableAttributedString = NSMutableAttributedString(string: strTitle)

    // give attribute to basic string
    title.addAttributes([NSForegroundColorAttributeName:UIColor.blue ,NSFontAttributeName:UIFont.boldSystemFont(ofSize: 15)], range: NSRange.init(location: 0, length: title.length))
    lableText.attributedText = title

    // give attribute to your range string
    let rangeOfString = lableText.text?.range(of: "Double tap") // this string is subString of strTitle
    title.addAttributes([NSForegroundColorAttributeName:UIColor.gray,NSFontAttributeName:UIFont.systemFont(ofSize: 15)], range: strTitle.nsRange(from: rangeOfString!))
    lableText.attributedText = title

}

J'espère que cela aidera.

1
vikas prajapati