Auto layout help

John Brownie

I have my web view displaying correctly, but I've run into a problem in getting the auto layout constraints working correctly. Basically, I build the appropriate web view as a subview of a custom view, which is in turn embedded in a view within a window. The problem is that, if I set constraints on the custom view, the window stops being resizable, and I can't work out why.

Here's the code for the constraints:

let variableBindings = ["webView": webView]
let constraints1 = NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[webView]-0-|", options: [], metrics: nil, views: variableBindings)
let constraints2 = NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[webView]-0-|", options: [], metrics: nil, views: variableBindings)

I have very similar code for the actual web view within its containing view. If I have only those and not the outer constraints, the window is resizable, but the container for the web view doesn't resize.

I must be doing something wrong, obviously, but I have run out of ideas on how to find my problem. Needless to say, this is the first time I've had to do auto layout in code.

Thanks for any insights,
John Brownie
Mussau-Emira language, New Ireland Province, Papua New Guinea
Kouvola, Finland

John Brownie

Further digging leaves me more confused. Because I'm supporting 10.9, there are various features I can't use, so I'm stuck with the auto layout basics, and it's hard to find a good explanation of how to set that up.

So, the window has a plain NSView in it, call it Container A. In the windowDidLoad of the window controller, I create an instance of the appropriate concrete subclass of MyWebView, which is the abstract class that captures the common behaviour I want, call it Container B, and make it a subview of Container A. The subclass creates its appropriate web view (WKWebView or WebView) and adds it as a subview of itself. So we have Container A containing Container B, which contains a web view.

What I want is to have zero margins around the web view and Container B, and have them resize as Container A is resized by resizing the window. My approach has been to set constraints in IB on Container A. When creating the web view, I add it as a subview of Container B and add constraints. When Container B has been created, I add it to Container A and add constraints. But somehow the constraints seem to be in the wrong places.

For debug purposes, I made the margins different at each level, and that gives me an unsatisfiable layout, as I have the different constraints conflicting.

The conclusion is that I don't know what I'm doing, and I haven't been able to find anything to explain how to set these up in code. Can anyone point me to a resource that tells me how to do this?


John Brownie

And I found the missing piece. I was failing to set translatesAutoresizingMaskIntoConstraints to false for one of the views. Doing that makes it all work.