0

I want to make the view look almost same on each of iPhone 6+, 6 and 5. In the attached picture, I mean, that, for example, "Cancel" button should be 30 pixels from left edge of screen in iPhone 5, 35 px in 6 and 45 px for 6+ and the similar for other elements.

How can specific constrains sizes be placed for each type of it? If I use proportions in constrains, so buttons grow, but their sizes not controlled and spaces between elements I cant change also. Size classes with specific constrains sizes I also can`t use, because cW aH is for 5 and 6 iphones the same. (as I understood).

I can`t figure out how to do it. How usually different designs for 6 and 6+ managed now?

enter image description here

Cesare
  • 9,139
  • 16
  • 78
  • 130
Dren
  • 2,017
  • 21
  • 18

2 Answers2

6

You can't target specific models of iPhone with Auto Layout. It's not meant for that. Auto Layout was built to avoid this. However, here are two workarounds:

Updated for iOS 9 and above

Use stack views. They're great for this kind of layout.

First option

Place an invisible UIView and create top, bottom, leading and trailing constraints attached to the Superview. After that, place your objects (they can be UIImageViews, UILabels and the list goes on) inside the UIView you have just placed. Now create top and bottom constraints that connect your objects to the UIView.

I created a demo to show you how it's done. As you will see, buttons have different sizes depending on the screen's size. Download the demo from this link.

Second option

You could create and modify constraints programmatically. Create a NSLayoutConstraint and adjust the constant of it depending on the user's device:

var myConstraint = NSLayoutConstraint (item: myButton,
        attribute: NSLayoutAttribute.Top,
        relatedBy: NSLayoutRelation.Equal,
        toItem: self.view,
        attribute: NSLayoutAttribute.Top,
        multiplier: 1,
        constant: 0)
    self.view.addConstraint(myConstraint)

if UIScreen.mainScreen().bounds.size.width == 375 {
    // iPhone 6
    myConstraint.constant = 10
} else if UIScreen.mainScreen().bounds.size.width == 414 {
    // iPhone 6+
    myConstraint.constant = 15
}
Cesare
  • 9,139
  • 16
  • 78
  • 130
  • 2
    *cough* as a general rule, never do direct comparisons on floats, as per the EDIT. In this case probably pick between 6 and 6+ with a > 395 or something similarly intermediary — apart from the floating point issue it'll make your code most likely to do something sensible if a new size comes along. But, you know, pedantry attack. I'm still going to vote positively for this answer. – Tommy Jan 22 '15 at 17:12
  • Sorry, I didnt figure out how to deal with it. Iam using XIBs and all controls now placed on internal view. It dont wont work. And I still cant specify exact values for spaces for different iphone devices without rotation. – Dren Jan 23 '15 at 10:27
  • How does it answers the question ? Be careful, UIScreen is interface oriented on iOS8, that means the width is no longer 375 on iPhone 6 landscape. **edit:** Oh, I see for the orange view in your example... It's a bit tricky ! – Crazyrems Jan 23 '15 at 14:06
0

Why do you need to pick 30, 35 and 45px ? Is there a reason for that pixelish placement ?


You can use more flexible constraints by using their multiply value instead of the constant.

The constraints adjusts themselves depending on the superview dimensions.

iPhone5 - iPhone 6 - iPhone 6+ - iPad - iPhone4 landscape Constraints demo

Note how my center X alignment constraints are configured:

enter image description here


enter image description here

You can see that the values behaves kind of strangely, sometimes multiplier is > 1, sometimes it's between 1 and 2, or < 1 depending on the order of First Item and Second Item. You still can swap their order by clicking on them and selecting Reverse First And Second Item.

Crazyrems
  • 2,551
  • 22
  • 40
  • I have layout prepared by designer. At real I provided with 6+ exact sizes, but cant make them looks good for 6 and 5s. First approach was in recalculating for 5s and internal scaling by device, which applied if I dont use splash screens for 6/6+. I was disired this result, bit it is not right. Now I want the same but backwards - put 6+ sizes and scale them proportionally for 6/5s, but got only mess. I used internal proportions in view cnstraints, but still not control prefered sizes and positions for elements. Thats it. – Dren Jan 23 '15 at 14:58
  • Hm.. You can always make an outlet of your constraints and set their constant when loading your view, like in [the edit of CeceXX](http://stackoverflow.com/a/28093987/1392046). Should fit more to your needs. – Crazyrems Jan 23 '15 at 15:11