5

I am simply trying to subclass UIWindow so that I can intercept some notifications. Along with the code listed below I also go into MainWindow.xib and update the UIWindow object to my sub class. It loads up fine, problem is the tabs on my tab bar are unresponsive (in the example below I only added one tab, but in my app I have multiple (that's not the problem)). Can anyone see what I might be doing wrong? Thanks.

UISubclassedWindow.h

#import <UIKit/UIKit.h>

@interface UISubclassedWindow : UIWindow 
{

}

@end

UISubclassedWindow.m

    #import "UISubclassedWindow.h"

    @implementation UISubclassedWindow

- (id) initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) 
    {
        NSLog(@"init");
    }
    return self;
}

    - (void)makeKeyAndVisible
    {
        [super makeKeyAndVisible];
        NSLog(@"makeKeyAndVisible");
    }

    - (void)becomeKeyWindow
    {
        [super becomeKeyWindow];
        NSLog(@"becomeKeyWindow");

    }

    - (void)makeKeyWindow
    {
        [super makeKeyWindow];
        NSLog(@"makekeyWindow");
    }

    - (void)sendEvent:(UIEvent *)event
    {
    }

    - (void)dealloc 
    {
        [super dealloc];
    }

    @end

AppDelegate.h

import

@class UISubclassedWindow;

@interface My_AppAppDelegate : NSObject <UIApplicationDelegate> 
{
    UISubclassedWindow *window;
}

@property (nonatomic, retain) IBOutlet UISubclassedWindow *window;

@end

AppDelegate.m

@synthesize window;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{   
    UITabBarController *tabBarController = [[UITabBarController alloc] init];

    MainViewController *mainViewController = [[MainViewController alloc] initWithViewType: 0];
    UINavigationController *mainNavigationController = [[UINavigationController alloc] initWithRootViewController: mainViewController];
    mainNavigationController.title = @"Main";
    [[mainNavigationController navigationBar] setBarStyle: UIBarStyleBlack];

    [tabBarController setViewControllers: [NSArray arrayWithObjects: mainNavigationController,  nil]];

    [self.window setRootViewController: tabBarController];
    [self.window makeKeyAndVisible];

    [mainViewController release];
    [mainNavigationController release];
    [tabBarController release];

    return YES;
}
Ser Pounce
  • 14,196
  • 18
  • 84
  • 169
  • maybe a dumb question, but did you set the class of the main window in your xib? – mvds Jan 13 '12 at 01:10
  • but why do you want this? if you put the right autoresizing masks then your view will align perfectly with the changing navbar. There is a valid reason that it shrinks a little in landscape. – mvds Jan 13 '12 at 01:14
  • @mvds - To your first comment, not a dumb question at all, because it was right. Now I've set the window to be my subclass in the mainwindow.xib (and also added the keyword outlet to the property) and when it loads it fires my NSLog messages, however, now the app is frozen. – Ser Pounce Jan 13 '12 at 01:18
  • @mvds - To your second comment, I just like the way it looks better, and I like having bigger buttons. It's only 12 pixel difference between the normal height, so I don't think it'll be hogging that much more space. – Ser Pounce Jan 13 '12 at 01:19

2 Answers2

4

The problem was I was including the UIWindows - (void)sendEvent:(UIEvent *)event method, but wasn't calling super on it. I called super on it and everything was fixed.

Ser Pounce
  • 14,196
  • 18
  • 84
  • 169
2

edit: note that this answers the original question, before a major rewrite changing the entire issue

You should first find out whether there is a documented way (some call, or an overridden method) to change the height of the nav bar. I highly doubt there is one. And I also doubt if UIWindow is the place to look for it - the nav bar is part of the UINavigationController.

Assuming there is no legal way to force the height to remain 44px, you can try several things:

  1. (not recommended) break the entire autorotation machinery of UINavigationController, handle the rotation of the view controllers yourself, e.g. from UIWindow, like you are starting to do now. The UINavigationController will only "feel" a resize and doesn't know it is actually rotating. The UINavigationController must not do rotations, so -shouldAutoRotate.. { return NO; }. As a quick check, see what happens if you would simply set the frame of the topmost VC to CGRectMake(0,0,480,320); (either from your subclassed UINavigationController or from the subclassed UIWindow). If everything still works OK, then you only need to add the autorotation part.
  2. (recommended) don't rely on UINavigationController for drawing navigation bars, but do it all yourself. Not much fun to do, but a 99% guarantee that you will get it working and it will not break on every update of iOS.
  3. (neutral, quick&dirty fix) for landscape mode, put your own UINavigationBar on top of the regular one.
mvds
  • 45,755
  • 8
  • 102
  • 111
  • Thanks for this long well thought out response. I changed the question just so you know, simplified it to just trying to get the subclass of UIWindow to work. – Ser Pounce Jan 13 '12 at 09:11
  • @CoDEFRo strange, I have a subclass just like that, and it just works. In my case I didn't override the methods you are, but that should not matter. I do override `-drawRect:`, `-sendEvent:`, `-canBecomeFirstResponder`, but I cannot imagine that this would somehow make a difference. Are you sure you didn't mess up anything else? – mvds Jan 13 '12 at 13:32