在
在带有 Swift 2 的 Xcode 7 中,它可以工作:

在带有 Swift 3 的 Xcode 8 中,链接的自定义属性颜色总是被忽略(在屏幕截图中应该是橙色)。

这是测试代码。
Swift 2,Xcode 7:
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import XCPlayground let text ="Hey @user!" let attr = NSMutableAttributedString(string: text) let range = NSRange(location: 4, length: 5) attr.addAttribute(NSForegroundColorAttributeName, value: NSColor.orangeColor(), range: range) attr.addAttribute(NSLinkAttributeName, value:"http://somesite.com/", range: range) let tf = NSTextField(frame: NSRect(x: 0, y: 0, width: 200, height: 50)) tf.allowsEditingTextAttributes = true tf.selectable = true tf.stringValue = text tf.attributedStringValue = attr XCPlaygroundPage.currentPage.liveView = tf |
Swift 3,Xcode 8:
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import PlaygroundSupport let text ="Hey @user!" let attr = NSMutableAttributedString(string: text) let range = NSRange(location: 4, length: 5) attr.addAttribute(NSForegroundColorAttributeName, value: NSColor.orange, range: range) attr.addAttribute(NSLinkAttributeName, value:"http://somesite.com/", range: range) let tf = NSTextField(frame: NSRect(x: 0, y: 0, width: 200, height: 50)) tf.allowsEditingTextAttributes = true tf.isSelectable = true tf.stringValue = text tf.attributedStringValue = attr PlaygroundPage.current.liveView = tf |
我已经向 Apple 发送了错误报告,但与此同时,如果有人对 Xcode 8 中的修复或解决方法有想法,那就太好了。
苹果开发者已经回答:
Please know that our engineering team has determined that this issue behaves as intended based on the information provided.
他们解释了为什么它以前有效但不再有效:
Unfortunately, the previous behavior (attributed string ranges with NSLinkAttributeName rendering in a custom color) was not explicitly supported. It happened to work because NSTextField was only rendering the link when the field editor was present; without the field editor, we fall back to the color specified by NSForegroundColorAttributeName.
Version 10.12 updated NSLayoutManager and NSTextField to render links using the default link appearance, similar to iOS. (see AppKit release notes for 10.12.)
To promote consistency, the intended behavior is for ranges that represent links (specified via NSLinkAttributeName) to be drawn using the default link appearance. So the current behavior is the expected behavior.
(强调我的)
此答案不能解决
通过这种解决方法,我们根本不使用
相反,我们使用自定义属性,并且子类化
显然有几个限制:您必须能够子类化字段/视图、覆盖
在准备
2 3 | theAttributedString.addAttribute(NSForegroundColorAttributeName, value: NSColor.orange, range: theLinkRange) theAttributedString.addAttribute(NSCursorAttributeName, value: NSCursor.arrow(), range: theLinkRange) |
设置了链接的颜色和内容。现在我们必须让它可点击。
为此,将您的
我们将获取鼠标事件在窗口中的位置,在该位置找到文本视图中的字符索引,并在文本视图的属性字符串中询问该索引处字符的属性。
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | override func mouseDown(with event: NSEvent) { // the location of the click event in the window let point = self.convert(event.locationInWindow, from: nil) // the index of the character in the view at this location let charIndex = self.characterIndexForInsertion(at: point) // if we are not outside the string... if charIndex < super.attributedString().length { // ask for the attributes of the character at this location let attributes = super.attributedString().attributes(at: charIndex, effectiveRange: nil) // if the attributes contain our key, we have our link if let link = attributes["CUSTOM"] as? String { // open the link, or send it via delegate/notification } } // cascade the event to super (optional) super.mouseDown(with: event) } } |
就是这样。
在我的例子中,我需要用不同的颜色和链接类型来定制不同的词,所以不是只将链接作为字符串传递,而是传递一个包含链接和其他元信息的结构,但想法是一样的。 如果您必须使用
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var referenceView: NSTextView {
let theRect = self.cell!.titleRect(forBounds: self.bounds)
let tv = NSTextView(frame: theRect)
tv.textStorage!.setAttributedString(self.attributedStringValue)
return tv
}
override func mouseDown(with event: NSEvent) {
let point = self.convert(event.locationInWindow, from: nil)
let charIndex = referenceView.textContainer!.textView!.characterIndexForInsertion(at: point)
if charIndex < self.attributedStringValue.length {
let attributes = self.attributedStringValue.attributes(at: charIndex, effectiveRange: nil)
if let link = attributes["CUSTOM"] as? String {
// ...
}
}
super.mouseDown(with: event)
}
}
我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2
我有这个html标记:我想得到这个:我如何使用Nokogiri做到这一点? 最佳答案 require'nokogiri'doc=Nokogiri::HTML('')您可以通过xpath删除所有属性:doc.xpath('//@*').remove或者,如果您需要做一些更复杂的事情,有时使用以下方法遍历所有元素会更容易:doc.traversedo|node|node.keys.eachdo|attribute|node.deleteattributeendend 关于ruby-Nokog
我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr
对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs
我想这样组织C源代码:+/||___+ext||||___+native_extension||||___+lib||||||___(Sourcefilesarekeptinhere-maycontainsub-folders)||||___native_extension.c||___native_extension.h||___extconf.rb||___+lib||||___(Rubysourcecode)||___Rakefile我无法使此设置与mkmf一起正常工作。native_extension/lib中的文件(包含在native_extension.c中)将被完全忽略。
在读取/解析文件(使用Ruby)时忽略某些行的最佳方法是什么?我正在尝试仅解析Cucumber.feature文件中的场景,并希望跳过不以Scenario/Given/When/Then/And/But开头的行。下面的代码有效,但它很荒谬,所以我正在寻找一个聪明的解决方案:)File.open(file).each_linedo|line|line.chomp!nextifline.empty?nextifline.include?"#"nextifline.include?"Feature"nextifline.include?"Inorder"nextifline.include?
我正在尝试查询我的Rails数据库(Postgres)中的购买表,我想查询时间范围。例如,我想知道在所有日期的下午2点到3点之间进行了多少次购买。此表中有一个created_at列,但我不知道如何在不搜索特定日期的情况下完成此操作。我试过:Purchases.where("created_atBETWEEN?and?",Time.now-1.hour,Time.now)但这最终只会搜索今天与那些时间的日期。 最佳答案 您需要使用PostgreSQL'sdate_part/extractfunction从created_at中提取小时
所以这可能有点令人困惑,但请耐心等待。简而言之,我想遍历具有特定键值的所有属性,然后如果值不为空,则将它们插入到模板中。这是我的代码:属性:#===DefaultfileConfigurations#default['elasticsearch']['default']['ES_USER']=''default['elasticsearch']['default']['ES_GROUP']=''default['elasticsearch']['default']['ES_HEAP_SIZE']=''default['elasticsearch']['default']['MAX_OP