2

For my 1) portrait only 2) deployment target iOS7/iOS8 app, I have in my design UIButtons which have variable heights, for iPhone 5, iPhone 6 and iPhone 6+. I am trying to use auto layout for this. (Not using size classes though).

Using auto layout how can I specify variable height for UIButton for these 3 screen sizes. The buttons look fine on iPhones 5* models, but thinner on iphone 6/6+. Now in auto layout I can say height >= or = or <= say 55), but how do I specify 44 for iphone5, 55 for iphone6, 66 for iphone6+?

Is this something that I can achieve using only auto layout or do I need to manupulate (frames) it in code? What is the point of me using auto layout then?

In addition to frames my designs also specify different font sizes. How do I go about this. Any best known methods for this, Stack-O friends .. ??

  • when using autolayout you should always work with constraints instead of with frame (constraints can be modified, animated...) – Rok Jarc Feb 11 '15 at 21:36
  • @rokjarc, thenhow do i specify varying heights using constraints in auto layout? –  Feb 11 '15 at 21:39
  • Thanks a bunch for all the replies .. I am going to try them all and see which one solves my particular problem. –  Feb 12 '15 at 00:26

3 Answers3

3

You are correct to ask "what is the point of auto-layout if I have to manipulate frames directly"? Thankfully, you don't have to.

An easy way of doing it is specifying the height in relation to a view of standard height (think a view that fits the whole screen).

For example, we can set our button's height to equal half the height of the view.

This way, the button is always going to scale with the view, either upwards or downwards (size-wise). Auto-layout will guarantee that the relation between them will always be 1/2.

enter image description here

enter image description here

Now the button will be half the size of its superview, regardless of size.

joakim
  • 3,533
  • 2
  • 23
  • 28
  • 1
    This is a nice way to provide adaptive layout however it's very unusual to satisfy designers requirements this way. Also in the case for this button you would want to provide very small multiplier values, and I've found this can be a problem in Xcode - I tried to get a hairline padding between 2 buttons at the bottom the screen once by setting auto layout width for the buttons to be equal to width of super view with multiplier 0.4999 and this just didn't work out. The precision was too inaccurate. Sounds like this guy needs to just be changing the constraint's constant at runtime unfortunately – Daniel Feb 11 '15 at 23:27
  • @Daniel Obviously, doing it manually will work too. Depending on the level of granularity each use case requires, either approach can fulfil the requirement. – joakim Feb 11 '15 at 23:32
1

It sounds like you need to be modifying the height constraints constant value.

In your xib/storyboard, create an outlet to your view/controller for the height constraint.

At runtime, probably in viewDidLoad, you will work out which device you're on, and then just change the constant of the height constraint.

CGFloat height;

// if iPhone 5
// height = 44
// else..........

self.buttonHeightConstraint.constant = height;

This will automatically trigger a flag that tells AutoLayout to recalculate frames and layout the view again.

Daniel
  • 23,129
  • 12
  • 109
  • 154
  • Keep in mind, that if this done outside 'viewDidLoad' the constraints might have to be updated. In the case of "leaf" nodes (e.g. UIButton, UIImageView) this has to be triggered by a call to 'invalidateIntrinsicContentSize'. – joakim Feb 11 '15 at 23:35
  • Thanks @Daniel, so far your advice is working well. I am still working on it. –  Feb 12 '15 at 20:35
  • Thanks Daniel and @joakim .. Your advice was spot on. What I have done so far is that I have connected the layout height constraint outlet to my *.m file and based on my screen size, I am setting the content property to the size I want . Working out well for me so far. For people wondering about how to connect layout constraints as outlets check this thread. http://stackoverflow.com/questions/22086054/unable-to-make-outlet-connection-to-a-constraint-in-ib –  Feb 12 '15 at 21:27
0

I managed this by adding a Height-Constraint to the UIButton. Make an Outlet and you can set the Height in your UIViewController subclass with _myConstraint.constant = 55;

Stephan Boner
  • 733
  • 1
  • 6
  • 27
  • So, do I need to have a bunch of #if's in the code then? For e.g #if iphone5 _myConstraint.constant = 44 #if iphone6 _myConstraint.constant = 55 #if iPhone6+ _myConstraint.constant = 66 –  Feb 11 '15 at 23:10
  • They can be runtime checks. At the moment there isn't any way to check device type in a storyboard, aside from class sizes, which may or may not be the behavior you want. – Jon Shier Feb 11 '15 at 23:23
  • No, you can handle it like this: `if ([[UIScreen mainScreen].bounds.size.height == 568) { _myConstraint.constant = 44; } //iPhone 5` – Stephan Boner Feb 12 '15 at 17:14