如果要使用主故事板文件,应用程序委托必须实现窗口属性

Posted

技术标签:

【中文标题】如果要使用主故事板文件,应用程序委托必须实现窗口属性【英文标题】:App delegate must implement the window property if it wants to use a main storyboard file 【发布时间】:2020-02-25 11:22:37 【问题描述】:

我已经尝试了在 *** 中可以找到的所有解决方案,但没有一个有效。

这是我当前的 AppDelegate.swift 文件,我认为我正在以某种方式实现 window 属性:

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate 

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool 
    // Override point for customization after application launch.
    window = UIWindow()
    window?.makeKeyAndVisible()
    let mainVC = UIViewController()
    window?.rootViewController = mainVC

    return true


// MARK: UISceneSession Lifecycle
@available(ios 13.0, *)
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration 
    // Called when a new scene session is being created.
    // Use this method to select a configuration to create the new scene with.
    window = UIWindow()
          window?.makeKeyAndVisible()
          let mainVC = UIViewController()
          window?.rootViewController = mainVC
    return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)


@available(iOS 13.0, *)
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) 
    // Called when the user discards a scene session.
    // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
    // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
    window = UIWindow()
          window?.makeKeyAndVisible()
          let mainVC = UIViewController()
          window?.rootViewController = mainVC

怎么回事,警告仍然出现,我的应用继续显示黑屏?

【问题讨论】:

【参考方案1】:

我一步一步指导你。

    第一次从项目中删除 SceneDelegate 文件。 将 var window: UIWindow? 添加到 AppDelegate。

    从 AppDelegate 中移除下面的函数。

    // MARK:UISceneSession 生命周期

    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration 
        // Called when a new scene session is being created.
        // Use this method to select a configuration to create the new scene with.
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    
    
    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) 
        // Called when the user discards a scene session.
        // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
        // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
    
    

    Info.plist 文件中删除 Application Scene Manifest 键。


额外

AppDelegate 文件中的 didFinishLaunchingWithOptions

下方添加委托方法
    func applicationWillResignActive(_ application: UIApplication) 
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
    

    func applicationDidEnterBackground(_ application: UIApplication) 
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    

    func applicationWillEnterForeground(_ application: UIApplication) 
        // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
    

    func applicationDidBecomeActive(_ application: UIApplication) 
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    

    func applicationWillTerminate(_ application: UIApplication) 
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    

【讨论】:

按照你的指示做了,但没有用,如果我没记错的话我已经试过了,还是谢谢你的帮助。 我认为您没有在情节提要中设置入口点。如果未设置,则更新您的函数,如下面的代码。 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool let navigation = UINavigationController(rootViewController: ViewController()) let frame = UIScreen.main.bounds window = UIWindow(frame: frame ) window!.rootViewController = 导航窗口!.makeKeyAndVisible() return true 还是一样,这真是个令人头疼的问题,无论如何感谢您的帮助。 我也为 swift 添加了答案。请检查以上【参考方案2】:

我刚刚在 AppDelegate 类中添加了var window: UIWindow?,问题得到了解决。

【讨论】:

答案非常适合 Swift。目标 C 的相同步骤,添加 @property(非原子,保留)IBOutlet UIWindow 窗口;到 AppDelegate.h【参考方案3】:

如果您正在开发一个 Objective C 应用程序并遇到此错误,请按照上述相同的步骤进行操作,仅在步骤 1 中进行更改。 将@property (nonatomic, retain) IBOutlet UIWindow window; 添加到 AppDelegate.h

【讨论】:

谢谢,但我正在使用 Swift。【参考方案4】:

当您在 Xcode 11.4 及更高版本中创建新项目时,您会使用 SceneDelegate 文件创建项目目录结构。

如果你尝试运行一个项目,你会得到一个错误。

第 1 步:删除 SceneDelegate.h 和 SceneDelegate.m

第 2 步:在 AppDelegate.h 中创建窗口属性。

@property (strong, nonatomic) UIWindow *window;

第 3 步:在主 Storyboard 中为 ViewController 设置 storyboard id。

并在appdelegate的didFinishLaunchingWithOptions方法中添加一个设置窗口。

UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:@"ViewController"];
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];

return YES;

对于 Swift:使用下面的代码

@UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate 

var window: UIWindow?

func application(_ application: UIApplication, 
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: 
  Any]?) -> Bool 
    // Override point for customization after application launch.
    return true

注意:不要在didFinishLaunchingWithOptions 方法中为swift添加窗口。

objective-ciosswift

【讨论】:

以上是关于如果要使用主故事板文件,应用程序委托必须实现窗口属性的主要内容,如果未能解决你的问题,请参考以下文章

从应用程序委托中呈现故事板视图控制器?

使用故事板从应用程序委托呈现模态视图控制器

没有故事板或 segue 的委托模式

删除 MainStoryboard 后黑屏

Xcode 故事板委托数据源场景

在主故事板顶部呈现锁定屏幕