22

I have strange problem with Xcode 6.1 GM.

let text: NSString = "A"
let font = NSFont(name: "Helvetica Bold", size: 14.0)

let textRect: NSRect = NSMakeRect(5, 3, 125, 18)
let textStyle = NSMutableParagraphStyle.defaultParagraphStyle().mutableCopy() as NSMutableParagraphStyle
textStyle.alignment = NSTextAlignment.LeftTextAlignment
let textColor = NSColor(calibratedRed: 0.147, green: 0.222, blue: 0.162, alpha: 1.0)

let textFontAttributes = [
    NSFontAttributeName: font,
    NSForegroundColorAttributeName: textColor,
    NSParagraphStyleAttributeName: textStyle
]

text.drawInRect(NSOffsetRect(textRect, 0, 1), withAttributes: textFontAttributes)

Error is in line let texFontAttributes...

Cannot convert the expression's type 'Dictionary' to type 'DictionaryLiteralConvertible'

This code is worked perfectly until Xcode 6.1 GM.

When I'm tried to declare textFontAttributes as NSDictionary error message is changed to:

Cannot convert the expression's type 'NSDictionary' to type 'NSString!'

I have no idea how to solve this problem :(

iPera
  • 1,053
  • 1
  • 12
  • 24
  • I don't know why, but `drawAtPoint:withAttributes:`, `drawInRect:withAttributes:`, `drawWithRect:options:attributes:`, `sizeWithAttributes:` and `boundingRectWithSize:options:attributes:` are “Not available in Swift” – JDS Oct 05 '14 at 14:05
  • @JDS It is unavailable not in Swift but Swift's *String* type. You can call those methods on *NSString* as did the OP. – Blaszard Mar 06 '15 at 12:59

5 Answers5

26

The problem is that font is optional because the convenience contructors now return optional values, so font needs to be unwrapped to be a value in your dictionary:

if let actualFont = font {
    let textFontAttributes = [
        NSFontAttributeName: actualFont,
        NSForegroundColorAttributeName: textColor,
        NSParagraphStyleAttributeName: textStyle
    ]

    text.drawInRect(NSOffsetRect(textRect, 0, 1), withAttributes: textFontAttributes)
}
vacawama
  • 150,663
  • 30
  • 266
  • 294
  • is it possible to apply gradient color to text with attributes using draw in rect in swift? you can check [question](https://stackoverflow.com/questions/67807362/apply-gradient-color-to-string-while-drawing-string-using-drawinwithattribut) also – Kishan Bhatiya Jun 03 '21 at 05:22
8

In Swift 4

    let attributeDict: [NSAttributedString.Key : Any] = [
        .font: font!,
        .foregroundColor: textColor,
        .paragraphStyle: textStyle,
    ]

    text.draw(in: rect, withAttributes: attributeDict)
AechoLiu
  • 17,522
  • 9
  • 100
  • 118
  • 1
    Now `NSAttributedString,Key` – Victor Engel Dec 11 '18 at 15:38
  • is it possible to apply gradient color to text with attributes using draw in rect in swift? you can check [question](https://stackoverflow.com/questions/67807362/apply-gradient-color-to-string-while-drawing-string-using-drawinwithattribut) also – Kishan Bhatiya Jun 03 '21 at 05:23
2

This is also another option.

let textFontAttributes = [
    NSFontAttributeName : font!,
    NSForegroundColorAttributeName: textColor,
    NSParagraphStyleAttributeName: textStyle
]
Randall Sutton
  • 1,875
  • 19
  • 27
1

In XCode 12, Swift 5.3. i was not able to find the draw method for String object. After i manually cast to NSString, it worked for me.

let text: String = "XXX"
(text as NSString).draw(in: rect withAttributes: attributes)
Li Jin
  • 1,879
  • 2
  • 16
  • 23
0

I have this piece of code in my app which works without problems:

    var textAttributes: [String: AnyObject] = [
        NSForegroundColorAttributeName : UIColor(white: 1.0, alpha: 1.0).CGColor,
        NSFontAttributeName : UIFont.systemFontOfSize(17)
    ]
zisoft
  • 22,770
  • 10
  • 62
  • 73
  • 2
    In iOS 8, using .drawAtPoint:withAttributes, that .CGColor causes a crash. It is expecting a UIColor. – bitmusher Aug 03 '15 at 19:57
  • @bitmusher ty, my app was crashing for mysterious reasons and your comment led me to the right cause. UIColor, not CGColor. You'd think the compiler could catch this, but those attributes packed into an array of strings is a little dangerous coming from Swift, which is otherwise very picky and explicit. – DrZ214 Dec 21 '15 at 07:07