How to pass multiple enum values as a function parameter

In Swift 2.1 we may use,

calculatedRect = (text as NSString).boundingRectWithSize(bounds.size, options: NSStringDrawingOptions([.UsesLineFragmentOrigin, .UsesFontLeading]), attributes: [NSFontAttributeName : font], context: nil)

to pass multiple enum values for a parameter.


Edit: In Swift 3.0:

let options: NSStringDrawingOptions = [.usesLineFragmentOrigin, .usesFontLeading]

Edit: This is how you would use the options enum in Swift 2.0:

let options: NSStringDrawingOptions = [.UsesLineFragmentOrigin, .UsesFontLeading]

Edit: The issue has been resolved in iOS 8.3 SDK Beta 1 (12F5027d):

Modified NSStringDrawingOptions [struct]

  • From: enum NSStringDrawingOptions : Int
  • To: struct NSStringDrawingOptions : RawOptionSetType

You can now write:

let options : NSStringDrawingOptions = .UsesLineFragmentOrigin | .UsesFontLeading

After some research and and @Anton Tcholakov's "comment":

  1. If you're targeting OS X 10.10, this is as simple way to do it:

    let size = CGSize(width: 280, height: Int.max)
    let options : NSStringDrawingOptions = .UsesLineFragmentOrigin | .UsesFontLeading
    
    let boundingRect = string.bridgeToObjectiveC().boundingRectWithSize(size, options: options, attributes: attributes, context: nil)
    
  2. However, in iOS 8 SDK (in the current seed), there's a bug, where NSStringDrawingOptions is ported to Swift as enum : Int, instead of struct : RawOptionSet. You should send a bug report to Apple describing this serious problem.


Updated answer for Xcode 6.3:

in Xcode 6.3 Beta (Swift 1.2) this is finally fixed, you can do it now like this:

let boundingRect = "string".boundingRectWithSize(size, options: .UsesLineFragmentOrigin | .UsesFontLeading, attributes:nil, context:nil)

For old version:

It looks like a bug in current beta, for now I write Objective-C method and use it from Swift:

+ (NSStringDrawingOptions)combine:(NSStringDrawingOptions)option1 with:(NSStringDrawingOptions)option2
{
    return option1 | option2;
}

and call form Swift:

let boundingRect = "string".boundingRectWithSize(size, options: StringDrawingOptions.combine(.UsesLineFragmentOrigin, with: .UsesFontLeading), attributes:nil, context:nil)

Another solution, use unsafeBitCast.

Like below:

let options = unsafeBitCast(NSStringDrawingOptions.UsesLineFragmentOrigin.rawValue | 
                            NSStringDrawingOptions.UsesFontLeading.rawValue,
                            NSStringDrawingOptions.self)

Tags:

Swift