[英]How to set constraints for iPhone 5s or iPhone SE only using storyboard in autolayout?
我正在嘗試使用故事板為特定的 iPhone SE 或 5s 使用 AutoLayout 設置約束。
您能否建議一些使用故事板的屏幕截圖來處理僅針對不同 iPhone 的限制?
iPhoneSE 和 iPhone6/7 之間 Storyboard 內部的區別是我期待已久的事情。 但不幸的是,我不得不意識到它們具有相同的大小等級,因此(據我所知)不可能為 Storyboard 內部的兩個設置約束差異。 (如果我錯了 - 請告訴我!!)。
但是,您可以在代碼中完成。
您可以使用AnchorPoints或LayoutAnchors在代碼中設置約束。 但通常,對於我的大多數情況,以下是這樣做的:
我在 UIDevice-ModelNames 周圍使用 Switch-case 並將 iPhoneSE 的 Layout-Constraints 設置為與 iPhone6/7(或我想區分的任何設備)不同。
話雖如此,在代碼中完全而不是故事板創建您的視圖(及其約束)通常是一個好主意。 但我認為,對於簡單的項目,快速提出 Storybard-Layout 及其約束設置有時仍然很有用。 然后我執行以下操作來區分 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
}
}
備注:使用模擬器請注意! 模擬器有它自己的 UIDevice-modelName,因此您需要在運行模擬器的設備大小中取消對 Devices.Simulator 的注釋(即根據模擬器運行的目標!)。 --> 請注意,每個 switch-case 都可以是 Simulator-Device !!
並且不要忘記在代碼庫中的某處定義您的設備:(--> 當然,當新的 Apple 設備出現時,您需要更新這些...)
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
}
}
}
iPhone SE 和 iPhone 6/7 具有相同的尺寸等級。 因此,您為 SE 創建的所有約束也將應用於 6。 但是您可以從代碼中操作它們。 檢查 UIScreen.main.bounds 並在必要時更新代碼中的約束。
您可以使用變體通過 defrance Device 設置約束。 但使用 Xcode 8.0 后,這里有一個新選項 Vary for Traits。
例如,您需要一個在 iPhone 和 iPad 中具有不同寬度的按鈕,然后它可以輕松完成和同時查看,而不是早期的 Size 類,其中為了檢查每個布局,我們必須打開預覽並選擇設備。
我添加了一個固定寬度為 135 的按鈕。
現在,如果我們要更改 iPad 的大小,請單擊右下角的“根據特性而變化”按鈕。 現在您可以根據需要選擇橫向或縱向。 還要選擇高度和寬度復選框。
我現在將寬度常量更改為 500。
然后作為確認,我們需要點擊“完成變化”按鈕。 之后屏幕看起來像
現在,當您返回到任何 iPhone 設備時,寬度約束將與之前在 iPhone 設備中設置的相同。
這就是“變化性狀”的全部內容。 我確實接受在不同的 iPhone/iPad + Orientaion 組合之間切換時使用“特征”時存在一些限制缺失的錯誤。
所以為了安全起見,我要求記住各種屏幕布局的 Size 類值,如
讓我知道您有任何疑問。
這不是很好,但至少比在代碼中做所有事情要容易一些。
因此,例如,如果您想要對 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)
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.