开始不使用故事板创建iOS项目

8

我遇到了使用xib而非storyboard启动iOS应用程序的一些问题。问题是我得到了一个黑屏,第一个视图控制器没有被调用(在viewDidLoad方法中添加了断点)。

在应用程序委托头文件中,我声明了以下内容:

@property (strong, nonatomic) UIWindow window;
@property (strong, nonatomic) ViewController *viewController;

didFinishLaunchingWithOptions 方法中,我有以下实现:

self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];

UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
navController.navigationBarHidden = YES;

self.window.rootViewController = navController;
[self.window makeKeyAndVisible];

浏览了一些论坛后,我发现应该分配窗口,因此我将其添加为函数的第一行。

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

问题在于,当我这样做时,在从didFinishLaunchingWithOptions方法返回后应用程序会崩溃(没有任何跟踪信息的SIGABRT)。
我还尝试将navController作为属性,并实例化一个默认的UIViewController类,使其与相同的xib initing。
我做错了什么?
谢谢和问候

你是否在目标的常规设置中删除了对“主”故事板的引用? - Jasper
@Jasper 是的,我已经删除了那里对Storyboard的引用,并且在info.plist中也进行了删除。我还尝试将ViewController.xib添加到常规设置中(但没有成功)。 - cobolero
就我所看到的,你做得一切都没问题。也许尝试清理你的项目,甚至删除派生数据。 - Jasper
@Jasper 我也尝试了这个解决方案,但它一直失败:S - cobolero
请问您能否更新 didFinishLaunchingWithOptions 的完整代码。 - Vishnuvardhan
@Vishnuvardhan 就像我发布的一样。 - cobolero
10个回答

8
希望这能帮到您:

删除视图控制器和故事板文件,新建viewController.h、viewController.h.m和viewController.xib文件。

 #import "AppDelegate.h"

 @interface AppDelegate ()

 @end

 @implementation AppDelegate
 @synthesize viewCOntrollerobj;

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
     self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
     self.viewCOntrollerobj = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
     UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self.viewCOntrollerobj];
     //navController.navigationBarHidden = YES;

     self.window.rootViewController = navController;
     [self.window makeKeyAndVisible];
     return YES;

}  

enter image description here


故事板及其引用已被删除。我发布了解决方案:只需删除并重新创建.h、.m和.xib文件即可。 - cobolero

3
在xCode 11中:
步骤1: - > 删除storyboard文件
步骤2: 在您的项目 > General > deployment info > main interface 下,删除对storyboard的引用。
步骤3: 在info.plist > Application Scene Manifest > Scene Configuration > Application Session Role > item 0 > storyboard name中, - > 删除该行
步骤4: 在SceneDelegate.m中。
 - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {

          self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
          self.window.windowScene = (UIWindowScene *)scene;
          self.window.rootViewController = [[UINavigationController alloc] 
                               initWithRootViewController:ViewController.new];
          [self.window makeKeyAndVisible];

}  

确保像这样导入您的viewController头文件:#import "ViewController.h"

2
要将项目从故事板更改为使用xib,请先为每个视图控制器创建一个xib。您需要将File's Owner更改为创建xib的视图控制器的类。然后将File's Owner视图输出链接到xib中的视图。
之后,选择您的应用程序目标,并将Main Interface下拉菜单更改为空。现在您可以删除storyboard文件。
最后,在app delegate的application:didFinishLaunchingWithOptions:方法中初始化窗口,并将初始视图控制器设置为窗口的根视图控制器。然后在您的app delegate的窗口上调用makeKeyAndVisible,您就可以开始了。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    self.window = [UIWindow new];
    self.window.rootViewController = [ViewController new];
    [self.window makeKeyAndVisible];
    return YES;
}

喜欢它。简洁、简单且有效(从info.plist中清除所有与storyboard相关的内容)。 - michael

1

好的,最后我明白了。

我需要做的就是再次添加

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

之后,只需删除.h、.m和.xib文件并重新创建它们。

出于某种原因,现在它可以正常工作了。


奇怪!你不应该这样做。至少很高兴你找到了解决方案。 - Joze
@Joze 我同意。无论如何,现在它已经可以工作了,呵呵。如果您再次遇到此问题,请尝试用这种方式解决。 - cobolero
如果有人感兴趣,这里提供了详细的步骤说明和图片,教你如何创建基本的单视图项目。http://xcodenoobies.blogspot.my/2015/10/how-to-create-basic-single-view-project.html - GeneCode
谢谢@Rocotilos。不管怎样,这似乎只是一个xCode的bug。 - cobolero

0

在Swift 3.0中

//MARK: Initial View Controller
func initialViewController(){
    self.window = UIWindow(frame: UIScreen.main.bounds)
    let rootViewController = UIViewController(nibName: "HomeVC", bundle: nil)
    let navigation : UINavigationController = UINavigationController(rootViewController: rootViewController)
    navigation.isNavigationBarHidden = true
    self.window?.rootViewController = navigation
    self.window?.makeKeyAndVisible()
}

in appdelegate.swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    initialViewController()

    return true
}

您不必指定“navigation”的类型。 - kkiermasz

0

这是一种“开箱即用”的解决方案,因此与您的代码无关。特别是我没有看到您的代码有任何问题。

我曾经遇到过同样的问题,并尝试了很长时间来修复代码,对我有效的方法是找到一个使用xibs的示例项目(例如在github上)。

下载它,然后编辑它以使您的应用程序保证正常工作。很遗憾Xcode想要强制我们使用他们的storyboards来解决这些问题。


我没有。我要试一试 - cobolero
2
一定要喜欢那些静音的投票者。如果你要投反对票,至少请留下评论,这样我就可以改进或直接删除我的回答,如果不合适的话。 - Joze

0

我没有尝试使用XIB,但这个东西在这里运行得很好:::

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.viewController = [[ViewController alloc] init];
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
    navController.navigationBarHidden = YES;

    self.window.rootViewController = navController;
    [self.window makeKeyAndVisible];
    // Override point for customization after application launch.
    return YES;
}

还有在ViewController的viewDidLoad方法里

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view setBackgroundColor:[UIColor greenColor]];
    // Do any additional setup after loading the view, typically from a nib.
}

屏幕上出现了绿色。

在为窗口设置根视图控制器之前,请初始化窗口。

这是我在你的代码中看到的唯一问题,因为根视图控制器被设置为一个空的窗口,然后你才进行初始化。


这里您没有使用指定的xib,而这正是OP想要的。 - Joze
我正在做这件事。就像我之前说过的那样,如果我实例化窗口,应用程序会在didFinishLaunchingWithOptions方法后崩溃,没有任何迹象。 - cobolero

0
  1. 将主界面保持为空enter image description here

  2. 将新的ViewController.xib添加到项目中,并将其文件所有者类标记为“ViewController” file's owner class as "ViewController"

  3. 在AppDelegate.m中

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    
    NSArray* xibContents = [[NSBundle mainBundle] loadNibNamed:@"ViewController"
                                                         owner:nil
                                                       options:nil];
    ViewController* vc = [xibContents objectAtIndex:0];
    UINavigationController *navigationController =
        [[UINavigationController alloc] initWithRootViewController:vc];
    self.window.rootViewController = navigationController;
    [self.window makeKeyAndVisible];
    
    return YES;
    

    }

  4. 构建并运行


xib文件的内容是一个视图 - cobolero

0

Xcode 11 带有 SceneDelegate

在 SceneDelegate.m 中

- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.windowScene = (UIWindowScene *)scene;
self.viewController = [[ViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
}

AppDelegate.m 文件中无需进行任何操作。


谢谢。我会回到过去,将其应用于一个iOS9-ObjC项目中:D - cobolero

0

iOS 16,Xcode 14 解决方案:

  1. 从项目导航器中删除 Main.storyboard
  2. 从 Info.plist 中删除 Storyboard 名称 Info.plist -> Information Property List -> Application Scene Manifest -> Scene Configuration -> Application Session Role -> Item 0
  3. 从 Info.plist 值中删除“UIKit Main Storyboard File Base Name” 目标 -> Build Settings -> Info.plist Values
  4. 在 SceneDelegate.swift 中添加代码

SceneDelegate -> scene(_:willConnectTo:options:)。

guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(frame: windowScene.coordinateSpace.bounds)
window?.windowScene = windowScene
window?.rootViewController = ViewController() // Your main VC
window?.makeKeyAndVisible()
```

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接