无法将类型“Range<String.Index>”(又名“Range<String.CharacterView.Index>”)的值转换为预期的参数类型“NSRange”(又
Posted
技术标签:
【中文标题】无法将类型“Range<String.Index>”(又名“Range<String.CharacterView.Index>”)的值转换为预期的参数类型“NSRange”(又名“_NSRange”)【英文标题】:Cannot convert value of type 'Range<String.Index>' (aka 'Range<String.CharacterView.Index>') to expected argument type 'NSRange' (aka '_NSRange') 【发布时间】:2017-09-15 05:13:50 【问题描述】:我正在尝试用属性字符串替换子字符串。以下是我的代码。
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
我收到编译时错误:
“无法将'Range'(又名'Range')类型的值转换为预期的参数类型'NSRange'(又名'_NSRange')”。
我应该在这里改变什么?
【问题讨论】:
name.range 可能是返回Range
和 replacingCharacters
需要方法 NSRange
@Jon Snow 有什么可以转换的吗?还是用不同的方法替换?
我尝试使用 NSString 作为 name,id 但得到不同的编译错误
比较NSRange from Swift Range?
【参考方案1】:
您可以使用NSString
和NSRange
,也需要更改这一行normalNameString.mutableString.replacingCharacters(in: range, with: attributedSubString)
并改用这一行 normalNameString.replaceCharacters(in: nsRange, with: attributedSubString)
因为 mutableString 是 NSMutableString,而 replacingCharacters
期望 String而不是NSAttributtedString
完整代码(针对 Swift5 更新)
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: [NSAttributedString.Key.font : 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
【讨论】:
当字符串中有多个表情符号时,这将不起作用。我刚遇到这个问题。 我的另一个字符串在应用属性文本后从白色变为黑色。为什么会这样? @KrutikaSonawala 你需要添加颜色属性NSAttributedString.Key.foregroundColor:UIColor.white
应该没问题【参考方案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】:您必须使用Range<String.index>
lowerBound
和UpperBound
位置值创建NSRange
实例,如下所示。
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
在searchtext constant
中添加self.searchBar.text!
而不是"Kiran"
和
根据您的要求在name constant
中添加item.firstName ?? ""
而不是"Kiran Jasvanee"
。
我已经在演示中尝试过,我发布的代码如下所示。请查收。
如果name = "AKiranJasvanee"
如果name = "KiranJasvanee"
【讨论】:
【参考方案4】:在 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)
【讨论】:
这一行normalNameString.mutableString.replacingCharacters(in: range, with: attributedSubString)
也会抛出一个错误,因为你使用attributedSubString 作为String
而是NSAttributedString
类以上是关于无法将类型“Range<String.Index>”(又名“Range<String.CharacterView.Index>”)的值转换为预期的参数类型“NSRange”(又的主要内容,如果未能解决你的问题,请参考以下文章
C# 无法将类型为“System.Byte[]”的对象强制转换为类型“System.Data.DataTable
无法将类型“[PHAsset]”的值分配给类型“UIImageView!”