【问题标题】:different storyboard based on phone model基于手机型号的不同故事板
【发布时间】:2015-11-24 19:53:00
【问题描述】:

我正在快速开发一个应用程序,它需要在 4S 以后的所有 iPhone 型号上运行,但我想在 4S 上以非常不同的方式布局,所以我想引导应用程序加载到完全不同的故事板中在4S。 我知道这可以在信息选项卡中为 iPad 完成,但设置主故事板文件基本名称 (iPad),但我找不到针对不同 iPhone 型号执行此操作的方法。 任何帮助将不胜感激

【问题讨论】:

  • 如果你使用 Swift,最好使用 Storyboard 的 SizeClasses,而不是使用不同的 Storyboard
  • 据我所知,你甚至不需要使用 Swift 来使用 Size Classes,你只需要 Xcode 6 或更高版本
  • 我一直在使用尺寸等级来限制 iPhone 5 及以后的版本,但我正在寻找一种方法让在 4s 上运行看起来完全不同的东西
  • 谢谢,我已经阅读了这个问题并且厌倦了实施该解决方案但没有成功。我希望有一种方法来选择使用代码加载哪个故事板,然后使用该question

标签: ios iphone swift storyboard


【解决方案1】:

您好,我认为您可以通过基于 iPhone 型号以编程方式加载不同的故事板来实现此目的

您可以将故事板用于任何设备型号,而不仅仅是 iPad 或通用 iPhone。

首先查看此链接how to determine device type

这是第一个想到的搜索,你可以找到它,它不让我知道会发布代码

然后你可以像下面这样加载设备特定的故事板

let storyboard: UIStoryboard
If 4s {
storyboard = UIStoryboard(name:"Main_4s.storyboard", bundle: NSBundle.mainBundle())
} else {
storyboard = UIStoryboard(name:"Main_default.storyboard", bundle: NSBundle.mainBundle())
}
let nc = storyboard.instantiateViewControllerWithIdentifier("navController")

然后将导航控制器设置为主 UI 窗口中的根视图控制器

UIApplication.sharedApplication().keyWindow?.rootViewContoller = nc 

注意:我还没有尝试过!

【讨论】:

  • 你的方法似乎很好用,你能告诉我如何让故事板从一个名为“FirstLaunch”的普通视图控制器开始,而不是通过导航控制器吗?跨度>
  • 用标识符“FirstLaunch”实例化视图控制器并将其设置为根视图控制器,您可以将任何视图控制器作为根视图控制器
【解决方案2】:

按照@HAShere的非常好的回答,你可以知道设备的型号。让我们创建一个名为DeviceModel 的快速文件,以保持扩展的各个部分分开。

DeviceModel.swift

import UIKit

private let DeviceList = [
                          /* iPod 5 */          "iPod5,1": "iPod Touch 5",
                          /* iPhone 4 */        "iPhone3,1":  "iPhone 4", "iPhone3,2": "iPhone 4", "iPhone3,3": "iPhone 4",
                          /* iPhone 4S */       "iPhone4,1": "iPhone 4S",
                          /* iPhone 5 */        "iPhone5,1": "iPhone 5", "iPhone5,2": "iPhone 5",
                          /* iPhone 5C */       "iPhone5,3": "iPhone 5C", "iPhone5,4": "iPhone 5C",
                          /* iPhone 5S */       "iPhone6,1": "iPhone 5S", "iPhone6,2": "iPhone 5S",
                          /* iPhone 6 */        "iPhone7,2": "iPhone 6",
                          /* iPhone 6 Plus */   "iPhone7,1": "iPhone 6 Plus",
                          /* iPad 2 */          "iPad2,1": "iPad 2", "iPad2,2": "iPad 2", "iPad2,3": "iPad 2", "iPad2,4": "iPad 2",
                          /* iPad 3 */          "iPad3,1": "iPad 3", "iPad3,2": "iPad 3", "iPad3,3": "iPad 3",
                          /* iPad 4 */          "iPad3,4": "iPad 4", "iPad3,5": "iPad 4", "iPad3,6": "iPad 4",
                          /* iPad Air */        "iPad4,1": "iPad Air", "iPad4,2": "iPad Air", "iPad4,3": "iPad Air",
                          /* iPad Air 2 */      "iPad5,1": "iPad Air 2", "iPad5,3": "iPad Air 2", "iPad5,4": "iPad Air 2",
                          /* iPad Mini */       "iPad2,5": "iPad Mini", "iPad2,6": "iPad Mini", "iPad2,7": "iPad Mini",
                          /* iPad Mini 2 */     "iPad4,4": "iPad Mini", "iPad4,5": "iPad Mini", "iPad4,6": "iPad Mini",
                          /* iPad Mini 3 */     "iPad4,7": "iPad Mini", "iPad4,8": "iPad Mini", "iPad4,9": "iPad Mini",
                          /* Simulator */       "x86_64": "Simulator", "i386": "Simulator"
                         ]

public extension UIDevice {

    var modelName: String {
        var systemInfo = utsname()
        uname(&systemInfo)

        let machine = systemInfo.machine
        let mirror = reflect(machine)                // Swift 1.2
        // let mirror = Mirror(reflecting: machine)  // Swift 2.0
        var identifier = ""

        // Swift 1.2 - if you use Swift 2.0 comment this loop out.
        for i in 0..<mirror.count {
            if let value = mirror[i].1.value as? Int8 where value != 0 {
                identifier.append(UnicodeScalar(UInt8(value)))
            }
        }

        // Swift 2.0 and later - if you use Swift 2.0 uncomment his loop
        // for child in mirror.children where child.value as? Int8 != 0 {
        //     identifier.append(UnicodeScalar(UInt8(child.value as! Int8)))
        // }

        return DeviceList[identifier] ?? identifier
    }
}

然后在didFinishLaunchingWithOptions 中的AppDelegate.swift 中,您可以实例化有关设备型号的故事板,如下所示:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    var storyboard: UIStoryboard

    // instantiate the `UIWindow`
    self.window = UIWindow(frame: UIScreen.mainScreen().bounds)

    // Get the model name based in the extension.
    let modelName = UIDevice.currentDevice().modelName

    // If the modelName variable contains the string "iPhone 6" inside.
    if (modelName.rangeOfString("iPhone 6") != nil) {
        storyboard = UIStoryboard(name: "iPhone6Storyboard", bundle: nil)
        self.window!.rootViewController = storyboard.instantiateInitialViewController() as! iPhone6ViewController
    }
    else if (modelName.rangeOfString("iPad") != nil) {
        storyboard = UIStoryboard(name: "iPadStoryboard", bundle: nil)
        self.window!.rootViewController = storyboard.instantiateInitialViewController() as! iPadViewController
    }

    self.window!.makeKeyAndVisible()

    return true
}

如果您添加了所需的UIStoryboard,则上述代码有效,使用Interface Builder 为每个UIStoryboard 设置其初始UIViewController(如果您不想设置初始@987654331 @使用Interface Builder,您可以很容易地找到如何以编程方式设置初始UIViewController,但为了简洁起见,我使用了Interface Builder。

当然,您需要在应用程序的设置中,转到您的目标和Info 选项卡。有清除Main storyboard file base name 的值。在General 选项卡上,清除主界面的值。您可以在此答案Programmatically set the initial view controller using Storyboards 中了解更多信息。

你需要注意两件事:

  • 在模拟器中你不能测试设备模型代码(它只给你'模拟器'),你需要真实的设备。
  • 您需要根据DeviceModel.swift中的代码正确使用设备名称以匹配不同的名称。

为简洁起见,我只在上面放了两个设备,但无论如何你需要根据名称匹配你想要的任何设备型号。

希望对你有所帮助。

【讨论】:

    猜你喜欢
    • 2016-06-27
    • 1970-01-01
    • 2015-07-14
    • 2012-06-13
    • 1970-01-01
    • 1970-01-01
    • 2017-05-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多