I have a series of objects with an optional "comment" field, which contains a string. I'd like to extract all the comments and list them as separate lines in an NSTextField (or any other suitable view). So I did this...
@IBOutlet var CommentsTextView: NSTextView!
func CommentsInitialize() {
var cmt = ""
for c in document!.commentCards {
cmt += c.info["comment"] ?? "" + "\n"
}
CommentsTextView.string = cmt
}
The text appears, but as all one line run together. According to this it should just work, but the newlines simply aren't doing anything (and I tried \n, \r\n and \r). Am I missing something obvious? I can see in IB that there's a setting in the TextStorage for the newline mode, but I can't seem to set it, changing the value does nothing.
p.s. If you're wondering about the missing "weak", apparently that's an old Cocoa issue - with the weak in there it released and died
The problem is that the nil coalescing operator ??
has a lower precedence (131
) than the +
operator (140
), hence the line:
cmt += c.info["comment"] ?? "" + "\n"
will be evaluated as
cmt += c.info["comment"] ?? ("" + "\n")
Subsequently, line break escape character "\n"
will be added to cmt
only if c.info["comment"]
contains nil.
If you replace the line with the following
cmt += (c.info["comment"] ?? "") + "\n" // (+)
then line breaks will be added also for cases where c.info["comment"]
is non-nil.
Now, the fixed procedure (+)
above will add line breaks also for empty (""
) as well as nil-valued comment fields, and also one final line break after the last comment field content. If you only want to add line breaks only for actual existing comments (not nil
neither empty), you could use if let
optional binding rather than the nil coalescing operator:
if let str = c.info["comment"] where str.characters.count > 0 {
cmt += str + "\n"
}
/* remove last trailing '\n' */
cmt.removeAtIndex(cmt.endIndex.advancedBy(-1))