我正在尝试使用故事板为特定iPhone SE或5s使用AutoLayout设置约束。
您能否使用故事板建议一些屏幕截图来处理不同IPhones的限制?
答案 0 :(得分:6)
iPhoneSE和iPhone6 / 7之间的故事板内部的区别是我很久以来一直在等待的。但不幸的是,我必须意识到他们有相同的大小级别,因此(据我所知)没有可能为两个内部故事板设置约束差异。 (如果我错了 - 请告诉我!!)。
但是,您可以在代码中执行此操作。
您可以使用AnchorPoints或LayoutAnchors在Code中设置约束。但通常情况下,以下情况适用于我的大多数情况:
我在我的UIDevice-ModelNames周围使用了一个Switch-case,并为iPhoneSE设置了不同于iPhone6 / 7的布局约束(或者我想要区分的任何设备)。
这就是说,在Code中完全创建你的Views(及其约束)通常是一个好主意,没有Storyboard。但我想,对于简单的项目,快速提出Storybard-Layout及其Constraint设置仍然有用。然后我执行以下操作来区分设备:
// 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
}
}
备注:如果您使用模拟器,请注意!模拟器有自己的UIDevice-modelName,因此您需要在运行模拟器的设备大小中取消注释Devices.Simulator注释(即根据您的模拟器运行的目标!)。 - >注意每个开关盒都可以是Simulator-Device !!
不要忘记在您的代码库中的某个位置定义您的设备: ( - >当然,你需要在新的Apple-Devices出来时更新这些......)
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
}
和...
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
}
}
}
答案 1 :(得分:5)
您可以使用变体设置defrance设备的约束。但是在这里使用Xcode 8.0是一个新的选项Vary for Traits。
例如,你需要一个在iPhone和iPad上有不同宽度的按钮,然后它可以很容易地完成并同时查看而不是早期的Size类,其中为了检查每个布局,我们必须打开预览并选择设备
我添加了一个固定宽度为135的按钮。
现在,如果我们想要更改iPad的尺寸,请点击右下角的按钮" Vary for Traits"。现在,您可以根据需要选择横向或纵向方向。还要选择身高和高度。宽度复选框。
我现在将宽度常量更改为500。
然后作为确认,我们需要点击"完成变更"按钮。屏幕看起来像
之后现在,当您返回任何iPhone设备时,宽度限制将与之前在iPhone设备中设置的相同。
这就是" Vary Traits"。我确实接受与#34; Traits"在不同的iPhone / iPad + Orientaion组合之间进行切换时,存在一些缺陷,一些限制因素缺失。
所以为了安全起见,我请求记住各种屏幕布局的Size类值,如
让我知道您有任何疑问。
答案 2 :(得分:4)
iPhone SE和iPhone 6/7具有相同的尺寸等级。因此,您为SE创建的所有约束也将应用于6。 但是你可以从代码中操纵它们。检查UIScreen.main.bounds并在必要时更新代码中的约束。
答案 3 :(得分:0)
这不是很好,但是至少比在代码中做所有事情容易。
例如如果要对LoginViewController设置不同的约束,则可以创建两个xib:LoginViewControllerSE.xib(对于SE)和LoginViewController.xib(对于其他手机),然后创建初始值设定项:
init() {
if UIDevice.current.modelName == Devices.IPhoneSE {
super.init(nibName: "LoginViewControllerSE", bundle: nil)
} else {
super.init(nibName: nil, bundle: nil)
}
}