簡體   English   中英

如何僅在自動布局中使用情節提要為 iPhone 5s 或 iPhone SE 設置約束?

[英]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 內部的兩個設置約束差異。 (如果我錯了 - 請告訴我!!)。

但是,您可以在代碼中完成。

您可以使用AnchorPointsLayoutAnchors在代碼中設置約束。 但通常,對於我的大多數情況,以下是這樣做的:

我在 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 屏幕,它會顯示為在此處輸入圖片說明

現在,如果我們要更改 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM