-1

In Chapter 4 of the Big Nerd Ranch: iOS Programming 4th Edition textbook where we're supposed to create a red rectangle appear in the middle of the view in the AppDelegate.m file and have it appear in the simulator.

I've copied the code word for word and when I run the simulator I get a blank screen like this:

Xcode Simulation

I'm not sure why this is happening. I've already put the property for window in the AppDelegate.h file so I know that's not why.

This is the code in the AppDelegate.m file:

//
//  AppDelegate.m
//  Hypnosister
//
//
//

#import "AppDelegate.h"
#import "BNRHypnosisView.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    CGRect firstFrame = CGRectMake(160, 240, 100, 150);
    
    BNRHypnosisView *firstView = [[BNRHypnosisView alloc]initWithFrame:firstFrame];
    firstView.backgroundColor = [UIColor redColor];
    [self.window addSubview:firstView];
    
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}


#pragma mark - UISceneSession lifecycle


- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {
    // Called when a new scene session is being created.
    // Use this method to select a configuration to create the new scene with.
    return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
}


- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet<UISceneSession *> *)sceneSessions {
    // 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.
}


@end

The Dreams Wind
  • 8,416
  • 2
  • 19
  • 49
  • What happens if you change `self.window.backgroundColor = [UIColor whiteColor];` to `self.window.backgroundColor = [UIColor blueColor];`. Does the white screen change to blue? I suspect the book you are using is out-of-date and doesn't cover the fact that iOS apps use scenes now and most of the code they have you put in the app delegate belongs in the scene delegate. – HangarRash May 14 '23 at 04:16
  • @HangarRash it still stays blank white. It should still work even if its out of date right? – nicktorres May 14 '23 at 05:19
  • *"It should still work even if it's out of date right?"* - not necessarily. New apps under iOS 13 or newer do not setup the window in the app delegate. It's done in the scene delegate. What year did the 4th edition of that book come out? What version of iOS was current back then? When it comes to programming, books get out-of-date before you even buy them. Find an up-to-date tutorial online. – HangarRash May 14 '23 at 05:38
  • The fact that the book uses Objective-C is an indication that it was published a long time ago (2014 according to Amazon). @HangarRash is absolutely correct, the window is created in the scene delegate since iOS 13. It is possible to revert back to the app delegate workflow but I think you would be wasting time and effort fighting more and more incompatibilities between the book and current behaviour. Learning Objective-C as a beginner is almost certainly not a good use of your time. Start with SwiftUI using a course such as https://www.hackingwithswift.com/100/swiftui – Geoff Hackworth May 14 '23 at 07:50
  • @GeoffHackworth the company i'm going to work for has their codebase still in Objective-C and the project I'll be working on will still be using it. They recommended me this book to read on before I start. Thanks for the recommendation though. – nicktorres May 14 '23 at 20:03
  • Yes it will work, if you use older versions of Xcode (the ones which supported iOS SDK 12 and below). Answer mentioned below by `The Dreams World` is the most suited answer in my view for your question: Use this inside sceneDelegate on iOS 13 and above. `self.window = [[UIWindow alloc] initWithWindowScene:(UIWindowScene *)scene]; self.window.backgroundColor = [UIColor redColor]; [self.window makeKeyAndVisible]; UIView *view = [[UIView alloc] initWithFrame: CGRectMake(160, 240, 100, 150)]; view.backgroundColor = UIColor.whiteColor; [self.window addSubview:view];` – learner May 15 '23 at 09:29

1 Answers1

1

If you use an application scene, the window you create manually in the application delegate is ignored (to be precise it remains the key window for very short period of time, until the scene makes its own window the key one). So you either should attach the window you created in the scene delegate's -[UISceneDelegate scene:willConnectToSession:options:] method:

- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
    UIWindow *window = [[UIWindow alloc] initWithWindowScene:(UIWindowScene *)scene];

    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(160, 240, 100, 150)];
    view.backgroundColor = UIColor.redColor;
    [window addSubview:view];

    window.backgroundColor = UIColor.whiteColor;
    [window makeKeyAndVisible];
    self.window = window;
}

..OR get rid of the scene delegate in your application (you may refer to the discussion under this question for more details on how to do it) and make it work with the old good application delegate's window. Be advised that in this case you won't be able to use the window without having the rootViewController specified, so you at least need to set a dummy controller:

_window.rootViewController = [UIViewController new];
The Dreams Wind
  • 8,416
  • 2
  • 19
  • 49