无法转换类型&#39;范围<string.index>&#39;的值(又名&#39;范围<string.characterview.index>&#39;)到预期的参数类型&#39; NSRange&#39; (又名&#39; _NSRange&#39;)

时间:2017-09-15 05:13:51

标签: ios swift nsattributedstring

我正在尝试用属性String替换子字符串。以下是我的代码。

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
}

我收到编译时错误:

  

&#34;无法转换类型&#39;范围&#39; (又名&#39;范围&#39;)预期参数类型&#39; NSRange&#39; (又名&#39; _NSRange&#39;)&#34;。

我应该在这里改变什么?

4 个答案:

答案 0 :(得分:9)

您可以使用NSStringNSRange,还需要更改此行normalNameString.mutableString.replacingCharacters(in: range, with: attributedSubString) 并使用此行 normalNameString.replaceCharacters(in: nsRange, with: attributedSubString),因为mutableString是NSMutableString和replacingCharacters期望String而不是NSAttributtedString

完整代码

    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
    }

答案 1 :(得分:2)

您必须使用NSRange Range<String.index>lowerBound位置值创建UpperBound实例,如下所示。

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
}  

self.searchBar.text! 中添加,"Kiran"代替searchtext constant  根据您的要求,在item.firstName ?? ""中添加"Kiran Jasvanee"而不是name constant

我已经在演示中试过了,我发布的代码工作正常,如下所示。请检查。
enter image description here

如果name = "AKiranJasvanee"
enter image description here
如果name = "KiranJasvanee"
enter image description here

答案 2 :(得分:2)

请这样做,

首先,

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

之后你有一个标签和字符串,

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

}

我希望它会有所帮助。

答案 3 :(得分:-1)

在Swift中Range不是NSRange类型。在这里,您传递的是Swift Range类型,其中包含NSRange,这就是您遇到错误的原因。

一种解决方法是,您可以将name转换为NSString以获取NSRange类型的范围,如下所示:

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

let subString = NSString(string: name).substring(with: range)
let attributedSubString = NSAttributedString.init(string:subString, attributes: [NSFontAttributeName : UIFont.boldSystemFont(ofSize: 17)])
let normalNameString = NSMutableAttributedString.init(string: name)
normalNameString.replaceCharacters(in: range, with: attributedSubString)