Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Autolayout Visual Format with Swift?

I've been trying to use the Autolayout Visual Format Language in Swift, using NSLayoutConstraint.constraintsWithVisualFormat. Here's an example of some code that does nothing useful, but as far as I can tell should make the type checker happy:

let foo:[AnyObject]! = NSLayoutConstraint.constraintsWithVisualFormat(   format: "", options: 0, metrics: {}, views: {}) 

However, this triggers the compiler error:

"Cannot convert the expression's type '[AnyObject]!' to type 'String!'".

Before I assume this is a Radar-worthy bug, is there anything obvious I'm missing here? This happens even without the explicit casting of the variable name, or with other gratuitous downcasting using as. I can't see any reason why the compiler would be expecting any part of this to resolve to a String!.

like image 490
Mike Walker Avatar asked Jun 12 '14 16:06

Mike Walker


People also ask

How do I use Autolayout in Xcode?

To create constraints select the button and click the Align icon in the auto layout menu. A popover menu will appear, check both “Horizontal in container” and “Vertically in container” options to center the button on the screen. Then click the “Add 2 Constraints” button. Run the application.

What is visual format?

In CSS The Visual Formatting Model describes how user agents take the document tree, and process and display it for visual media. This includes continuous media such as a computer screen and paged media such as a book or document printed by browser print functions.

What is Nslayoutconstraint?

The relationship between two user interface objects that must be satisfied by the constraint-based layout system.


2 Answers

this works for me with no error:

let bar:[AnyObject]! = NSLayoutConstraint.constraintsWithVisualFormat(   nil, options: NSLayoutFormatOptions(0), metrics: nil, views: nil) 

update

the line above may not be compiled since the 1st and 4th parameters cannot be optionals anymore.

syntactically those have to be set, like e.g. this:

let bar:[AnyObject] = NSLayoutConstraint.constraintsWithVisualFormat("", options: NSLayoutFormatOptions(0), metrics: nil, views: ["": self.view]) 

update

(for Xcode 7, Swift 2.0)

the valid syntax now requests the parameters's name as well, like:

NSLayoutFormatOptions(rawValue: 0) 

NOTE: this line of code shows the correct syntax only, the parameters itself won't guarantee the constraint will be correct or even valid!

like image 81
holex Avatar answered Oct 22 '22 19:10

holex


The first gotcha here is that Swift Dictionary is not yet bridged with NSDictionary. To get this to work, you'll want to explicitly create a NSDictionary for each NSDictionary-typed parameters.

Also, as Spencer Hall points out, {} isn't a dictionary literal in Swift. The empty dictionary is written:

[:] 

As of XCode 6 Beta 2, this solution allows you to create constraints with the visual format:

var viewBindingsDict: NSMutableDictionary = NSMutableDictionary() viewBindingsDict.setValue(fooView, forKey: "fooView") viewBindingsDict.setValue(barView, forKey: "barView") self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-[fooView]-[barView]-|", options: nil, metrics: nil, views: viewBindingsDict)) 
like image 34
John M. P. Knox Avatar answered Oct 22 '22 19:10

John M. P. Knox