为什么我的游乐场在 NSRange() 上崩溃
Why does my playground crash on NSRange()
我正在尝试了解 NSMutableAttributedString
和 NSAttributedString
,所以我创建了一个简单的 playground 来尝试一些事情。但是,即使在查看了很多关于 SO 的示例(例如 here and NSRange from Swift Range? 其他地方。
之后,我仍然无法弄清楚几个问题
问题出在长度 属性 上。如果我将长度指定为 attribLabelText.length
,则会导致未捕获的异常。如果我指定 attribLabelText.length - 1
没有错误,但只有字母 'Repor' 具有我正在设置的属性:
import UIKit
import PlaygroundSupport
class MyViewController : UIViewController {
override func loadView() {
let view = UIView()
view.backgroundColor = .white
let label = getLabel1(labelText: "Report")
view.addSubview(label)
self.view = view
}
}
func getLabel1(labelText: String) -> UILabel {
let label = UILabel()
label.frame = CGRect(x: 150, y: 200, width: 200, height: 20)
label.textColor = .black
let attribLabelText: NSMutableAttributedString = NSMutableAttributedString(string: labelText)
let attributes = [
NSAttributedString.Key.foregroundColor : UIColor.gray.cgColor,
NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 14)
] as [NSAttributedString.Key : Any]
attribLabelText.addAttributes(attributes, range: NSRange(location: 0, length: attribLabelText.length)) <-- this causes an uncaught exception of type NSException
label.attributedText = attribLabelText
return label
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
我觉得这将是显而易见的事情,但我没有想法去尝试。谁能指出我做错了什么?
您应该为前景色传递 UIColor
而不是 CGColor
。
UILabel 在绘制字符串时似乎使用前景色属性略有不同,具体取决于该属性是覆盖字符串的整个范围还是仅覆盖一个子范围。
当属性覆盖整个字符串时它使用的版本仅适用于 UIColor
但当属性仅覆盖子字符串时它使用的版本似乎也适用于 CGColor
(尽管此行为没有记录,所以不应该依赖它)这解释了为什么将 -1 添加到范围中可以避免异常。
我正在尝试了解 NSMutableAttributedString
和 NSAttributedString
,所以我创建了一个简单的 playground 来尝试一些事情。但是,即使在查看了很多关于 SO 的示例(例如 here and NSRange from Swift Range? 其他地方。
问题出在长度 属性 上。如果我将长度指定为 attribLabelText.length
,则会导致未捕获的异常。如果我指定 attribLabelText.length - 1
没有错误,但只有字母 'Repor' 具有我正在设置的属性:
import UIKit
import PlaygroundSupport
class MyViewController : UIViewController {
override func loadView() {
let view = UIView()
view.backgroundColor = .white
let label = getLabel1(labelText: "Report")
view.addSubview(label)
self.view = view
}
}
func getLabel1(labelText: String) -> UILabel {
let label = UILabel()
label.frame = CGRect(x: 150, y: 200, width: 200, height: 20)
label.textColor = .black
let attribLabelText: NSMutableAttributedString = NSMutableAttributedString(string: labelText)
let attributes = [
NSAttributedString.Key.foregroundColor : UIColor.gray.cgColor,
NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 14)
] as [NSAttributedString.Key : Any]
attribLabelText.addAttributes(attributes, range: NSRange(location: 0, length: attribLabelText.length)) <-- this causes an uncaught exception of type NSException
label.attributedText = attribLabelText
return label
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
我觉得这将是显而易见的事情,但我没有想法去尝试。谁能指出我做错了什么?
您应该为前景色传递 UIColor
而不是 CGColor
。
UILabel 在绘制字符串时似乎使用前景色属性略有不同,具体取决于该属性是覆盖字符串的整个范围还是仅覆盖一个子范围。
当属性覆盖整个字符串时它使用的版本仅适用于 UIColor
但当属性仅覆盖子字符串时它使用的版本似乎也适用于 CGColor
(尽管此行为没有记录,所以不应该依赖它)这解释了为什么将 -1 添加到范围中可以避免异常。