【问题标题】:Is it possible to migrate an old Xcode project to use SwiftUI?是否可以迁移旧的 Xcode 项目以使用 SwiftUI?
【发布时间】:2019-10-24 05:03:52
【问题描述】:

我有一个使用 Main.storyboard 在 Xcode 10 中制作的应用程序,并希望将其迁移以使用 Apple 的新框架:SwiftUI。
这已经可能了吗?

我已经尝试在Info.plist 中添加UIApplicationSceneManifest 键,我将AppDelegate.swift 更改为使用场景,我创建了SceneDelegate.swift,即使那样我也无法

【问题讨论】:

  • 你遇到什么样的错误?
  • 启动LaunchScreen.storyboard后,屏幕变黑
  • 有一些要求...(1) Xcode 11 beta 1, (2) 设备需要是 iOS13 beta 1, (3) 如果你想使用 Xcode 11 Previews, 在 macOS 10.15 上运行卡塔利娜。即使在那里,也没有没有迁移者。此外,SwiftUI 替换 Storyboard 并且不使用 AutoLayout。建议非常慢一点——从一个新项目开始。如果您必须使用现有的应用程序,请记住,任何 SwiftUI 组件将需要 iOS13 到2019 年秋季。
  • 谢谢。满足所有要求。我现在打算为正在使用测试版的人使用 testflight,并为 iOS13 发布时准备我的应用程序
  • 我也出现黑屏,但在我的情况下,它不依赖于使用SwiftUI。我在 Xcode 11 中创建了一个带有情节提要的空项目,并决定删除这个情节提要并手动添加视图控制器。错误是我在“app delegate”中添加了这段代码,但应该在“scene delegate”中做类似的事情。

标签: ios swift xcode swiftui


【解决方案1】:

我假设您使用的是 Xcode 11 GM 和 macOS MojaveCatalina

随着plist 的变化,您必须在应用程序委托中添加UISceneSession 生命周期函数。

func application(_ application: UIApplication,
                 configurationForConnecting connectingSceneSession: UISceneSession,
                 options: UIScene.ConnectionOptions) -> UISceneConfiguration {
    // The name must match the one in the Info.plist
    return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}

func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {

}

另外,您需要确保在SceneDelegate 中正确创建window

func scene(_ scene: UIScene, 
           willConnectTo session: UISceneSession, 
           options connectionOptions: UIScene.ConnectionOptions) {

    guard let windowScene = scene as? UIWindowScene else {
        return
    }

    let window = UIWindow(windowScene: windowScene)
    window.rootViewController = UIHostingController(rootView: ContentView())
    self.window = window
    window.makeKeyAndVisible()
}

其中ContentView 是您要显示的主要SwiftUI 视图。

附:确保plist 指定$(PRODUCT_MODULE_NAME).SceneDelegate 作为委托类名,并且场景委托被称为SceneDelegate

例子:

如果您使用的是Catalina,则可以在目标的构建设置中打开Previews

构建选项 -> 启用预览


附录一

确保从 Info.Plist 中删除 Storyboard 键和 you're targeting iOS 13


附录二

清洁 Derived Data,正如 cmets 中的许多开发人员所建议的那样。

【讨论】:

  • @AiltonVieiraPintoFilho 请检查答案底部的 Addendum I 以获取更多说明 - 我刚刚在使用 Xcode 10.2.1 的项目 createad 上尝试了所有这些,我得到了它的工作
  • 我返回了提交,再次尝试,它成功了。谢谢!
  • 面临同样的问题。我必须彻底清理派生数据并从模拟器中删除应用程序才能使更改生效。
  • 我已经搞砸了好几个小时。我已经按照上述检查了所有设置,但没有任何效果。我在应用程序委托中设置了断点,并注意到传入的场景会话具有外部显示的作用。我已经尝试了各种方法,但无法正确加载。如果我在调试控制台上手动创建具有应用程序角色的场景配置,它会完美加载。所以问题似乎是应用程序以某种方式决定它是一个外部显示器,我找不到任何改变它的东西。
  • 如何更改 mac 应用程序的 rootview 控制器。我正在将我的旧 iPhone 转换为 mac,并且在用户登录一次应用程序后。如果用户再次打开应用程序,我需要更改情节提要。我在这方面面临问题。
【解决方案2】:

结果证明我的解决方案有所不同。在我的情况下,我已经准备好了所有东西,但是当代码尝试加载UISceneConfiguration 时,它无法加载Info.plist 中的配置,而是给了我一个辅助窗口配置,而不是没有设置场景委托。如果我从调试控制台询问正确的配置,它将按预期加载。我很困惑。

我仔细检查了所有内容并尝试了这里的所有建议,但都没有奏效。最后我在模拟器上做了 'Hardware' - 'Erase all contents and settings...' 就解决了。

我的猜测是,因为我一直在模拟器上运行应用程序的 SwiftUI 之前版本,导致 SwiftUI 版本的行为有所不同。

【讨论】:

  • 在设备上,删除应用并重新安装
  • 哇,我在我正在迁移的项目中到处搜索,怀疑自己。做到了!
  • 对我来说,它正确设置了委托,但我没有将 sceneClass 设置为 (null)
【解决方案3】:

这是一个正确的小改动

SceneDelegate.swift 中替换

let window = UIWindow(frame: UIScreen.main.bounds)
window.rootViewController = UIHostingController(rootView: ContentView())
self.window = window
window.makeKeyAndVisible()

if let windowScene = scene as? UIWindowScene {
    let window = UIWindow(windowScene: windowScene)
    window.rootViewController = UIHostingController(rootView: ContentView())
    self.window = window
    window.makeKeyAndVisible()
}

取自HERE

【讨论】:

    猜你喜欢
    • 2020-12-04
    • 2011-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多