8

Im having some troubles to start an iOS app using xibs instead of storyboard. The problem is that im getting a black screen and the first view controller is not being called (added break point to viewDidLoad method).

In the app delegate header i have declared this:

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

And in the didFinishLaunchingWithOptions method i have this implementation:

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];

Looking over some forums i found that i should be allocing the window so i added this as the first line of the function

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

The problem is that, when i do this, the app crashes after returning from didFinishLaunchingWithOptions method (SIGABRT without any trace).

I also tried to make the navController a property and also instantiating a default UIViewController class initing the same xib

What am i doing wrong?

Thanks and regards

cobolero
  • 412
  • 1
  • 6
  • 13

10 Answers10

8

Hope this helps you:

Delete the view controller and storyboard file and new viewController.h,viewController.h.m ,viewController.xib file.

 #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

soumya
  • 3,801
  • 9
  • 35
  • 69
  • the storyboard and its references were already deleted. I posted the solution: just delete and create again the .h, .m and .xib – cobolero Aug 04 '15 at 10:02
3

In xCode 11:

Step1:

-> Delete the storyBoard file

Step2:

Under yourProject > General > deployment info > main interface -> delete reference to storyboard

Step 3:

In info.plist > Application Scene Manifest > Scene Configuration > Application Session Role > item 0 > storyboard name

-> Delete the line

Step 4:

In 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];

}  

make sure to import your viewController headfile like so: #import "ViewController.h"

Gautier
  • 103
  • 1
  • 4
2

To change your project to use xibs instead of storyboards start by creating a xib for each view controller. You will need to change the File's Owner to class to the view controller you are creating the xib for. Then link the File's Owner view outlet to the view in the xib.

After that, select your app target and change the Main Interface drop down to be empty. Now you can delete the storyboard file.

Finally, initialize your window in the app delegate's application:didFinishLaunchingWithOptions: method and set your initial view controller as the root view controller of the window. Then call makeKeyAndVisible on your app delegate's window and you should be good to go.

- (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;
}
1

OK, at last i got it.

What i had to do is just add again

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

After this, just delete the .h, .m and .xib and create them again.

For any reason its working fine now.

cobolero
  • 412
  • 1
  • 6
  • 13
  • Strange! You shouldn't have to do that. Glad you found your solution at least. – Jose Luis Aug 04 '15 at 11:30
  • @Joze i agree. Whatever, its working now hehe. If you have this problem again try to fix it in this way – cobolero Aug 04 '15 at 11:41
  • If anybody's interested, here is detailed step by step on how to do this with pictures. http://xcodenoobies.blogspot.my/2015/10/how-to-create-basic-single-view-project.html – GeneCode Oct 05 '15 at 10:43
  • thaks @Rocotilos. Anyway it seems it was just a xCode bug – cobolero Oct 05 '15 at 10:46
0

This is a kind of "out of the box" solution, so it is irrelevant to your code. Specially since I don't see anything wrong with your code.

I had the same problem and tried for a long time to fix the code, what worked for me was finding an example project (in github for example) that uses xibs.

Download it and then edit it to make your application it is guaranteed to work. It is a shame that Xcode wants to force us to use their storyboards with these kinds of problems.

Jose Luis
  • 3,307
  • 3
  • 36
  • 53
0

I didnt try with XIB, but this thing is working fine here:::

- (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;
}

and in ViewController's viewDidLoad

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

And the green color comes on the screen.

Initialize the window before setting the root view controller for the window.

That's the only problem that i see in you code, as the rootViewController is set to a nil window, and after that you are initializing.

Vikas Dadheech
  • 1,672
  • 12
  • 23
  • Here you are not using the specified xib, and that is exactly what the OP wants. – Jose Luis Aug 04 '15 at 08:56
  • im doing this. As i told before, if i instantiate the window the app crashes with no trace afther the `didFinishLaunchingWithOptions` method – cobolero Aug 04 '15 at 09:02
0
  1. Leave main interface emptyenter image description here

  2. Add new ViewController.xib to the project and mark its file's owner class as "ViewController" file's owner class as "ViewController"

  3. In 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. build and run

Prabhu.Somasundaram
  • 1,380
  • 10
  • 13
0

In 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
}
Pablo Ruan
  • 1,681
  • 1
  • 17
  • 12
0

Xcode 11 with SceneDelegate

In 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];
}

No need to do anything in AppDelegate.m

iOS dev
  • 470
  • 7
  • 23
0

iOS 16, Xcode 14 solution:

  1. Delete the Main.storyboard from Project navigator
  2. Remove Storyboard Name from Info.plist
 Info.plist -> Information Property List -> Application Scene Manifest -> Scene
 Configuration -> Application Session Role -> Item 0
  3. Delete “UIKit Main Storyboard File Base Name” from Info.plist Values
 Target -> Build Settings -> Info.plist Values
  4. Add the code in 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()
```
Neha Vipin
  • 688
  • 6
  • 17