简体   繁体   English

基于启动 storyboard 加载屏幕偏离中心?

[英]Loading screen off centre based on launch storyboard?

I have 2 storyboards: Onboarding and Main.我有 2 个故事板:入职和主要。 Everything works great as far as execution goes.就执行而言,一切都很好。 The issue is that I have loading screen at the start of Main.storyboard that looks different depending on which storyboard launches.问题是我在 Main.storyboard 的开头有加载屏幕,这取决于 storyboard 启动的不同。

Scenario 1: New user launches the app, it goes through Onboarding.storyboard then Main.storyboard launches and the loading screen looks as it should like this: Correct Screen场景 1:新用户启动应用程序,它通过 Onboarding.storyboard 然后 Main.storyboard 启动,加载屏幕看起来应该是这样的:正确屏幕

Scenario 2: User launches the app for the second time, therefore Onboarding.storyboard is not launched: Loading screen is off centre like this: Wrong Screen场景 2:用户第二次启动应用程序,因此 Onboarding.storyboard 未启动:加载屏幕偏离中心,如下所示:错误屏幕

Long story short: If there is no Onboarding.storyboard, it doesn't look right.长话短说:如果没有 Onboarding.storyboard,它看起来不正确。 The issue is only shown on iPad landscape;该问题仅在 iPad 横向上显示; portrait looks fine.肖像看起来不错。

All of my loading screen code is inside my first view controller of Main.Storyboard so I'm guessing that the issue is the order in which the code is called?我所有的加载屏幕代码都在我的第一个视图 controller 的 Main.Storyboard 所以我猜问题是调用代码的顺序?

Onboarding.Storyboard only has 1 view controller Main.Storyboard goes: TabBarController -> NavController -> FirstVC Onboarding.Storyboard 只有 1 个视图

I placed my SceneDelegate code below along with the loading screen code of FirstVC.我将我的 SceneDelegate 代码与 FirstVC 的加载屏幕代码放在下面。

In case you want to dig in deeper, I'm using RevealingSplashView available on github.如果您想深入挖掘,我使用 github 上提供的 RevealingSplashView。 Since I don't think that's the issue I didn't get into that further.因为我不认为这是我没有深入探讨的问题。

SceneDelegate:场景委托:

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

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

    window = UIWindow(frame: windowScene.coordinateSpace.bounds)
    window?.windowScene = windowScene

    let onboardingStoryboard = UIStoryboard(name: "Onboarding", bundle: nil)
    let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
    var vc: UIViewController

    if UserDefaults.standard.value(forKey: "firstTimer") == nil {
        vc = onboardingStoryboard.instantiateInitialViewController()!
    } else {
        vc = mainStoryboard.instantiateInitialViewController()!
    }

    self.window?.rootViewController = vc
    self.window?.makeKeyAndVisible()
}

FirstVC relevant code: FirstVC相关代码:

class firstVC: UIViewController {

    var revealingSplashView : RevealingSplashView!

override func viewDidLoad() {
    super.viewDidLoad()

    showLoadingScreen()
}

func showLoadingScreen() {

       revealingSplashView = RevealingSplashView(iconImage: UIImage(named: "Icon")!, iconInitialSize: CGSize(width: 150, height: 150), backgroundImage: UIImage(named: "loadBackground")!)
       revealingSplashView.animationType = .heartBeat
       revealingSplashView.startAnimation()

       view.addSubview(revealingSplashView)
}

Check to see that your layout constraints are the same in both of your storyboards.检查两个故事板中的布局约束是否相同。 I'd recommend just setting them to center horizontal and center vertical on both of them.我建议将它们设置为水平居中和垂直居中。

In your scene delegate callback, why are you calling instantiateInitialViewController() twice per storyboard?在您的场景委托回调中,您为什么要为每个 storyboard 调用两次 instantiateInitialViewController()?

In my iOS 12 project, I used storyboards to kick things off.在我的 iOS 12 项目中,我使用故事板来开始。 In app delegate didFinishLaunching, I would override and set the window if and only if it was a new user.在应用程序委托 didFinishLaunching 中,当且仅当它是新用户时,我会覆盖并设置 window。 So my "Main" storyboard would kick in most of the time.所以我的“主要” storyboard 大部分时间都会启动。

Same technique could be applied here.在这里可以应用相同的技术。 Check out the Info.plist values you need to set for UIScene storyboard to work.查看您需要为 UIScene storyboard 设置的 Info.plist 值。 You can override the window if you want to show the first time onboarding, otherwise let the system instantiate your main storyboard.如果您想显示第一次入职,您可以覆盖 window,否则让系统实例化您的主 storyboard。

Further testing revealed that if I return SceneDelegate to its "factory default" state, therefore launching Main.storyboard, I had no issues.进一步的测试表明,如果我将 SceneDelegate 恢复为其“出厂默认值”state,因此启动 Main.storyboard,我没有任何问题。

To fix the issue I simply changed my SceneDelegate to:为了解决这个问题,我只是将我的 SceneDelegate 更改为:

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

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

    if UserDefaults.standard.value(forKey: "firstTimer") == nil {

        window = UIWindow(frame: windowScene.coordinateSpace.bounds)
        window?.windowScene = windowScene

        let onboardingStoryboard = UIStoryboard(name: "Onboarding", bundle: nil)
        var vc: UIViewController

        vc = onboardingStoryboard.instantiateInitialViewController()!

        self.window?.rootViewController = vc
        self.window?.makeKeyAndVisible()
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM