如何仅在autolayout中使用故事板设置iPhone 5s或iPhone SE的约束?

时间:2017-04-20 13:30:56

标签: ios iphone autolayout storyboard

我正在尝试使用故事板为特定iPhone SE或5s使用AutoLayout设置约束。

您能否使用故事板建议一些屏幕截图来处理不同IPhones的限制?

4 个答案:

答案 0 :(得分:6)

iPhoneSE和iPhone6 / 7之间的故事板内部的区别是我很久以来一直在等待的。但不幸的是,我必须意识到他们有相同的大小级别,因此(据我所知)没有可能为两个内部故事板设置约束差异。 (如果我错了 - 请告诉我!!)。

但是,您可以在代码中执行此操作。

您可以使用AnchorPointsLayoutAnchors在Code中设置约束。但通常情况下,以下情况适用于我的大多数情况:

我在我的UIDevice-ModelNames周围使用了一个Switch-case,并为iPhoneSE设置了不同于iPhone6 / 7的布局约束(或者我想要区分的任何设备)。

这就是说,在Code中完全创建你的Views(及其约束)通常是一个好主意,没有Storyboard。但我想,对于简单的项目,快速提出Storybard-Layout及其Constraint设置仍然有用。然后我执行以下操作来区分设备:

enter image description here

// 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的按钮。

enter image description here

如果我们现在选择一个iPad屏幕,它就会显示出来 enter image description here

现在,如果我们想要更改iPad的尺寸,请点击右下角的按钮" Vary for Traits"。现在,您可以根据需要选择横向或纵向方向。还要选择身高和高度。宽度复选框。

enter image description here

我现在将宽度常量更改为500。

enter image description here

然后作为确认,我们需要点击"完成变更"按钮。屏幕看起来像

之后

enter image description here

现在,当您返回任何iPhone设备时,宽度限制将与之前在iPhone设备中设置的相同。

enter image description here

这就是" Vary Traits"。我确实接受与#34; Traits"在不同的iPhone / iPad + Orientaion组合之间进行切换时,存在一些缺陷,一些限制因素缺失。

所以为了安全起见,我请求记住各种屏幕布局的Size类值,如

enter image description here

让我知道您有任何疑问。

答案 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)
    }
}