17

I have a ViewController designed for iPhone SE

enter image description here

As you can see I also have a constraint Align Top to: Safe Area Equals 75

The question is, is it possible to change this value for iPhone 8 and iPhone 8 Plus? For example:

  • SE = 75
  • 8 = 85
  • 8 Plus = 105
xskit
  • 421
  • 1
  • 8
  • 20
  • 1
    You could consider an alternative constraint; constrain the bottom of the square to the center of the superview. – Paulw11 Feb 06 '18 at 20:18
  • 1
    If you really need to do such, then constraints is the way.However 2 tips 1. Try using [`readableContentGuide`](https://stackoverflow.com/a/47614397/5175709). I know this won't make any changes for you. Only that Apple has got these values based on extensive studies. You shouldn't have a design that requires such2. Try constraining it to the top, but then modify its [`contentcompressionresistancepriority`](https://stackoverflow.com/a/16281229/5175709) vs other views'. Also [here](https://medium.com/@abhimuralidharan/ios-content-hugging-and-content-compression-resistance-priorities-476fb5828ef) – mfaani Feb 06 '18 at 20:25

4 Answers4

23

Easy way!

To overcome this issue I created a small library so you don't have to write a single line of code just assign the class (NSLayoutHelper) to your constraint and you'll be able to update your constraint for all the devices differently.

enter image description here

For updating constraints

enter image description here

Output

enter image description here

Community
  • 1
  • 1
tryKuldeepTanwar
  • 3,490
  • 2
  • 19
  • 49
10

we were facing similar issue. We solved with helper class called scaled. Which basically just multiply size of something, which should appear larger on larger device.

extension CGFloat {
    public var scaled: CGFloat {
        switch UIDevice.type.getResolutionGroup()! {
        case .lr320x568:
            return self
        case .lr375x667:
            return self * 1.1
        case .lr414x736:
            return self * 1.2
        case .lr768x1024:
            return self * 1.3
        // For iPads
        case .lr1024x1366:
            return self * 1.3
        }
    }
}

And implementation of resolution group

public func getResolutionGroup() -> ResolutionGroup? {
        switch self {
        case .iPhone5, .iPhone5C, .iPhone5S, .iPhoneSE, .iPodTouch5, .iPodTouch6:
            return .lr320x568
        case .iPhone6, .iPhone6S, .iPhone7:
            return .lr375x667
        case .iPhone6Plus, .iPhone6SPlus, .iPhone7Plus:
            return .lr414x736
        case .iPadMini, .iPadMini2, .iPadMini3, .iPadMini4:
            return .lr768x1024
        case .iPad2, .iPad3, .iPad4, .iPadAir, .iPadAir2:
            return .lr768x1024
        case .iPadPro:
            return .lr1024x1366
        case .simulator:
            return isiPhone() ? .lr320x568 : .lr768x1024
        default:
            return .lr320x568
        }
    }

And usage in app

fileprivate let footerHeight = CGFloat(180).scaled
Jakub Průša
  • 2,255
  • 1
  • 14
  • 19
8

Not using Interface Builder, no. Constraints, can only target Compact, Regular or Any sizes and all iPhone models have Compact width and Regular height when in portrait mode.

If you want that kind of granularity, you have to do it with code instead.

rodskagg
  • 3,827
  • 4
  • 27
  • 46
  • Thank you for the answer. Can you please write your mind about what is it better to use when I have a ViewController perfect looks on SE and too much empty space on iPhone 8 Plus for example? Do I need to change constraints in code? – xskit Feb 06 '18 at 20:20
  • 3
    Yes. Create an outlet for your constraint and change its constant to the values you want, depending on the size of your viewcontroller's view (or the device screen size). – rodskagg Feb 06 '18 at 20:23
2

This is not applicanle in IB , you can try in code by hooking the top constraint of the view as IBOutlet and in viewDidLayoutSubviews

override func viewDidLayoutSubviews()
{

   if(deviceWidthSE)
   {      
      self.viewTopCon.constant = 75
   }
   else
   if(deviceWidth8)
   {
      self.viewTopCon.constant = 85
   }
   else
   if(deviceWidth8Plus)
   {
      self.viewTopCon.constant = 105
   }

}
Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87