Stretching Views with Auto Layout on iOS

I am busy porting my Windows Phone app to Android and iOS, and everything seems to be going quite well. I am using MvvmCross with Xamarin Platform Tools and there is much code reuse.

This is a simple app, literally two screens that could actually be merged into a single screen: A ID number entry form and a status page with a few lines of text. However an app is an app and an Android, iOS and Windows Phone app is still just awesome to have.

This is my first attempt at creating an iOS app from scratch. I have done a couple of Android apps for various companies, but iOS is still ultra new for me. So far as I can see, Apple has created a huge API with many great interfaces. The iOS API is more mature than the Android API, and this shows in many areas.

One of the awesome features that I came across is the Auto Layout features of creating interfaces. My app’s start screen has a view that contains the controls and an image view underneath. The controls view is of a fixed size as it just contains a text box and a button, but the image scaled to fit the remaining space.

On Windows Phone, I was just using a Grid with an expandable row and set the image to fill it. On Android, I placed the image view inside a LinearLayout and set the weight to 1. On iOS, I wasn’t sure… I recalled from my previous dabbling that there was some Autoresizing options, but after reading around, there seems to be something better, Auto Layout.

Eventually, I discovered that this is quite powerful, but a little more complex. What I needed to do was set the image view to be “anchored” at various points. In this case, the image was to expand to fill the space, so I naturally set the top, left bottom and right sides to be pinned at a nice space from the edge of the screen.

I expected the view, if pinned at the top and at the bottom, would grow as the points moved apart, unfortunately for me, there was something that I missed. The height. When I looked around, there was a little icon showing that there was a problem with my constraints. It picked up that there was a problem with the heights of my views, but I wasn’t sure what to do exactly.

My first solution to the problem, but actually wasn’t a solution was to see if there was a way to tell the image view to be expandable. For some reason it did not occur to me that if it was growing horizontally and not vertically, I needed to check to see what was different there. But anyway, I found a little option called “Intrinsic Size” and if I set this to “Placeholder” all the errors went away, but sadly for me, this has little to do with my problem. Intrinsic Size is for when there is shadows or other decoration features that the layout engine should ignore. Even though there were no errors, the actual app on the device just failed and the image was stretched over everything. Sad.

So, it finally occurred to me that if my image was anchored below the controls view, I may actually need to specify a height for the controls. This is not exactly intuitive as it should use the designer’s size automatically, but that’s just me. Anyway, after giving the controls view a height, the running app now correctly stretched my image from the bottom of the view to the bottom of the screen, or, filled the space. Yay!

Because I am cool with images, and Balsamiq Mockups, I have prepared an image for the viewers:

Auto Layout on iOS