views:

215

answers:

3

I'm having a problem when trying to add a UITabBar as a subview of my AppDelegate's window. The link above shows a screenshot of the messy state of the screen.

TabBarInAMessyState.png

The results are unpredictable. In this picture only the UITabBarItem's titles were affected, but sometimes the TabBar background is not shown (consequently we can see the window's background). Sometimes the NavigationBar is also affected (not show in this picture).

When I start the Application I first have to check if there's network connection, so It is called a method (verifyNetworkAvailability:) that will run in a thread different from the main thread. This is done in order not to freeze the application.

- (void)applicationDidFinishLaunching:(UIApplication *)application {
        [window makeKeyAndVisible];

        // check if there's network connection in another thread
        [NSThread detachNewThreadSelector: @selector(verifyNetworkAvailability:) toTarget:self withObject:self];
    }

    - (void) verifyNetworkAvailability:(MyAppDelegate*) appDelegate {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

        // Check if there's network connection..
        // If so, call the verifyNetworkAvailabilityDidEnd method 
        [appDelegate verifyNetworkAvailabilityDidEnd];

        [pool release];
    }

    - (void) verifyNetworkAvailabilityDidEnd {
        [window addSubview:tabBarController.view];
    }

I'd like to know if it is possible to add the tabBarController.view in this way (by a method call done in thread other than the main thread).

Thanks in advance

A: 

UIKit has some trouble when you try to access it from any thread but the main thread. Think about dispatching a notification to have your primary app thread to add the view rather than adding the view directly in your secondary thread.

Tim
I tried using the NSNotificationCenter but with no success.See the post below for more details.
Eduardo Coelho
A: 

It tried to solve this problem using the NSNotificationCenter, but with no success.

The code below shows the current implementation:

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    [window makeKeyAndVisible];

    [[NSNotificationCenter defaultCenter]  addObserver:self selector:@selector(verifyNetworkAvailabilityDidEnd) name:kNetworkCheckingNotificationName object:Nil];

    [NSThread detachNewThreadSelector: @selector(verifyNetworkAvailability:) toTarget:self withObject:self];
}

- (void) verifyNetworkAvailability:(MyAppDelegate*) appDelegate {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    // Check if there's network connection..
    // If so, post the notification
    [[NSNotificationCenter defaultCenter] postNotificationName:kNetworkCheckingNotificationName object:self];

    [pool release];
}

 - (void) verifyNetworkAvailabilityDidEnd {
    [window addSubview:tabBarController.view];
}

It seems that the "verifyNetworkAvailabilityDidEnd" method isn't being executed in the main thread. Both TabBar and NavigationBar are still being rendered with problems. Any hints?

Thanks in advance.

Eduardo Coelho
Try using `[window performSelectorOnMainThread:@selector(addSubview:) withObject:tabBarController.view waitUntilDone:YES];`
Tim
Thanks! Now it is working perfectly!
Eduardo Coelho
A: 

Try this

- (void) verifyNetworkAvailability:(MyAppDelegate*) appDelegate {
    // other code here ...

    [appDelegate performSelectorOnMainThread:@selector(verifyNetworkAvailabilityDidEnd) withObject:nil waitUntilDone:NO];
}
nduplessis
Thanks!!! It worked perfectly!!!
Eduardo Coelho
You're welcome :)
nduplessis