I am trying to set the constraints using AutoLayout for a particular iPhone SE or 5s using storyboard.
Can you please suggest some screenshots using storyboard to handle the constraints for different IPhones only?
The distinction inside Storyboard between iPhoneSE and iPhone6/7 is something I am waiting for since a long time. But unfortunately, I had to realise that they have the same size-class and that therefore there is (to my knowledge) no possibility to set-up constraint-differences for the two inside Storyboards. (if I am wrong - please let me know !!).
However, you can do it in code.
You can use AnchorPoints or LayoutAnchors to set your constraints inside Code. But usually, the following does it for most of my cases :
I use a Switch-case around my UIDevice-ModelNames and set the Layout-Constraints for the iPhoneSE differently to the iPhone6/7 (or whatever Device I want to distinguish).
This being said, it is probably usually a good idea to create your Views (and its constraints with it) in Code entirely and without Storyboards. But I figured, for simple projects, it is still sometimes useful to quickly come up with a Storybard-Layout and also its Constraint-settings. Then I do the following to distinguish Devices :
// create the constraint-outlet by CTRL-drag
// one of your defined Constraint-lines from
// Storyboard directly to your Code
@IBOutlet weak var bannerWidthConstraint: NSLayoutConstraint!
// then for example inside viewDidLoad, set the outlet's constant to the value needed...
// Distinguish manually between UIDevices...
override func viewDidLoad() {
switch UIDevice.current.modelName {
case Devices.IPhone5, Devices.IPhone5S, Devices.IPhone5C:
//, Devices.Simulator:
self.bannerWidthConstraint.constant = 73
case Devices.IPhone6, Devices.IPhone6S, Devices.IPhone7, Devices.IPhone8:
//, Devices.Simulator:
self.bannerWidthConstraint.constant = 96
case Devices.IPhone6Plus, Devices.IPhone6SPlus, Devices.IPhone7Plus, Devices.IPhone8Plus:
//, Devices.Simulator:
self.bannerWidthConstraint.constant = 110
case Devices.IPhoneX:
//, Devices.Simulator:
self.bannerWidthConstraint.constant = 96
default:
self.bannerWidthConstraint.constant = 73
}
}
Remark: Please pay attention if you use the Simulator ! The Simulator has its own UIDevice-modelName and therefore you need to uncomment the Devices.Simulator comment in the Device-Size you are running you Simulator with (ie according to the Target your Simulator runs with!). --> Notize that each switch-case can be the Simulator-Device !!
And don't forget to define your Devices somewhere in your Code-Base: (--> of course, you need to update these when new Apple-Devices come out...)
public enum Devices: String {
case IPodTouch5
case IPodTouch6
case IPhone4
case IPhone4S
case IPhone5
case IPhone5C
case IPhone5S
case IPhone6
case IPhone6Plus
case IPhone6S
case IPhone6SPlus
case IPhone7
case IPhone7Plus
case IPhoneSE
case IPhone8
case IPhone8Plus
case IPhoneX
case IPad2
case IPad3
case IPad4
case IPad5
case IPadAir
case IPadAir2
case IPadMini
case IPadMini2
case IPadMini3
case IPadMini4
case IPadPro_9_7
case IPadPro_12_9
case IPadPro_12_9_2ndGen
case IPadPro_10_5
case AppleTV_5_3
case AppleTV_6_2
case HomePod
case Simulator
case Other
}
And...
public extension UIDevice {
public var modelName: Devices {
var systemInfo = utsname()
uname(&systemInfo)
let machineMirror = Mirror(reflecting: systemInfo.machine)
let identifier = machineMirror.children.reduce("") { identifier, element in
guard let value = element.value as? Int8 , value != 0 else { return identifier }
return identifier + String(UnicodeScalar(UInt8(value)))
}
switch identifier {
case "iPod5,1": return Devices.IPodTouch5
case "iPod7,1": return Devices.IPodTouch6
case "iPhone3,1", "iPhone3,2", "iPhone3,3": return Devices.IPhone4
case "iPhone4,1": return Devices.IPhone4S
case "iPhone5,1", "iPhone5,2": return Devices.IPhone5
case "iPhone5,3", "iPhone5,4": return Devices.IPhone5C
case "iPhone6,1", "iPhone6,2": return Devices.IPhone5S
case "iPhone7,2": return Devices.IPhone6
case "iPhone7,1": return Devices.IPhone6Plus
case "iPhone8,1": return Devices.IPhone6S
case "iPhone8,2": return Devices.IPhone6SPlus
case "iPhone9,1", "iPhone9,3": return Devices.IPhone7
case "iPhone9,2", "iPhone9,4": return Devices.IPhone7Plus
case "iPhone8,4": return Devices.IPhoneSE
case "iPhone10,1", "iPhone10,4": return Devices.IPhone8
case "iPhone10,2", "iPhone10,5": return Devices.IPhone8Plus
case "iPhone10,3", "iPhone10,6": return Devices.IPhoneX
case "iPad2,1", "iPad2,2", "iPad2,3", "iPad2,4":return Devices.IPad2
case "iPad3,1", "iPad3,2", "iPad3,3": return Devices.IPad3
case "iPad3,4", "iPad3,5", "iPad3,6": return Devices.IPad4
case "iPad4,1", "iPad4,2", "iPad4,3": return Devices.IPadAir
case "iPad5,3", "iPad5,4": return Devices.IPadAir2
case "iPad6,11", "iPad6,12": return Devices.IPad5
case "iPad2,5", "iPad2,6", "iPad2,7": return Devices.IPadMini
case "iPad4,4", "iPad4,5", "iPad4,6": return Devices.IPadMini2
case "iPad4,7", "iPad4,8", "iPad4,9": return Devices.IPadMini3
case "iPad5,1", "iPad5,2": return Devices.IPadMini4
case "iPad6,3", "iPad6,4": return Devices.IPadPro_9_7
case "iPad6,7", "iPad6,8": return Devices.IPadPro_12_9
case "iPad7,1", "iPad7,2": return Devices.IPadPro_12_9_2ndGen
case "iPad7,3", "iPad7,4": return Devices.IPadPro_10_5
case "AppleTV5,3": return Devices.AppleTV_5_3
case "AppleTV6,2": return Devices.AppleTV_6_2
case "AudioAccessory1,1": return Devices.HomePod
case "i386", "x86_64": return Devices.Simulator
default: return Devices.Other
}
}
}
iPhone SE and iPhone 6/7 have the same size class. So, all the constraints you created for SE will be applied for 6 too. But you can manipulate them from code. Check UIScreen.main.bounds and update your constraints in code if necessary.
You can set constraints with defrance Device using variants. but have used Xcode 8.0 here is one new option Vary for Traits.
For example, you need a button having different widths in iPhone and iPad, then it can be easily done and viewed at the same time rather than the earlier Size classes wherein for checking each layout , we had to open the preview and select devices.
I have added a button with fixed width 135.
If we select an iPad screen now, it shows like
Now if we want to change the size for iPad, then click on the button in the bottom-right corner "Vary for Traits". Now you are good to go with selecting landscape or portrait orientations as per need. Also select height & width tickboxes.
I am now changing the width constant to 500.
Then as a confirmation, we need to click on "Done varying" button. After which the screen looks like
Now when you go back to any of the iPhone devices, the width constraint will be the same as earlier set in iPhone device.
That was all about "Vary Traits". I do accept that on working with "Traits" while changing between different iPhone/iPad + Orientaion combinations there are bugs that some constraints go missing.
So just to be on safe side, I request to keep in mind the Size class values for various screen layouts as in
Let me know you have any query.
This is not great, but at least is little easier than doing everything in code.
So, eg if you want different constraints for LoginViewController, you can create two xibs: LoginViewControllerSE.xib (for SE) and LoginViewController.xib (for other phones) and then create initializer:
init() {
if UIDevice.current.modelName == Devices.IPhoneSE {
super.init(nibName: "LoginViewControllerSE", bundle: nil)
} else {
super.init(nibName: nil, bundle: nil)
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.