White screen after presenting a modal view controller - objective-c

I'm getting a white screen after presenting a modal view controller. This is how I do it:
SomeViewController *controller = [[[SomeViewController alloc] initWithManagedObjectContext:managedObjectContext] autorelease];
UINavigationController *navController = [[[UINavigationController alloc] initWithRootViewController:controller] autorelease];
[navController setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
[self presentModalViewController:navController animated:YES];
The navigation bar works fine, as I set it up in SomeViewController, but the view's contents are not visible, and all I see is the white background color of the root window.
The strange thing is, that this used to work, but now it doesn't for some reason.
What could be the problem?
EDIT:
This is how I create SomeViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
[self setTitle:#"Some View"];
UIBarButtonItem *sortButton = [[[UIBarButtonItem alloc] initWithTitle:#"Sort" style:UIBarButtonItemStylePlain target:self action:#selector(sortButtonClicked:)] autorelease];
[[self navigationItem] setRightBarButtonItems:[NSArray arrayWithObjects:sortButton, [self editButtonItem], nil] animated:YES];
UIBarButtonItem *backButton = [[[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStylePlain target:self action:#selector(dismissModalViewControllerAnimated:)] autorelease];
[[self navigationItem] setLeftBarButtonItem:backButton];
// Hack to force landscape orientation
UIViewController *controller = [[UIViewController alloc] init];
[self presentModalViewController:controller animated:NO];
[self dismissModalViewControllerAnimated:NO];
[controller release];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (void) viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}

The white screen was caused by the xib file of the controller not being part of the target(its target membership checkbox was unchecked).

Do you happen to have some other init meted also in the SomeViewController class? Please post the whole .m file. If so, you can try to delete the initWithNibName method and check if it shows the content.
EDIT:
Another strange point is the initWithManagedObjectContext method you are using on the viewController instance. Can you explain it?

try
SomeViewController *controller = [[[SomeViewController alloc] init] autorelease];
it should work fine.

Related

Instance variables not working in ViewController in UINavigationController

I'm still new to iOS development but I've ran into a problem that I can't solve and I've tried looking online but can't find anything yet.
I'm using a UIImagePickerController to pick and image and I'm using it in the App Delegate. When an image is returned, in the imagePickerController:didFinishPickingMediaWithInfo method, I want to make a new navigation controller with a view controller and put it over the "app".
Here is how I'm doing it:
CustomNavigationController *customNavigationController = [[CustomNavigationController alloc] init];
PhotoViewController *photoViewController = [[PhotoViewController alloc] initWithNibName:#"PhotoViewController" bundle:[NSBundle mainBundle]];
[customNavigationController pushViewController:photoViewController animated:NO];
[customNavigationController.view setFrame:[[UIScreen mainScreen] applicationFrame]];
[photoViewController release];
[self.window addSubview:customNavigationController.view];
//Call method of photoViewController.
[[customNavigationController.viewControllers objectAtIndex:0] addPhotoFromData:info];
[self.tabBarController dismissViewControllerAnimated:YES completion:nil]; //Get rid of UIImagePickerController
However in the photoViewController, I don't have access to any instance variables synthesized and loaded in viewDidLoad. They all return to null. There is also a tableView and calls to reload the tableView do not actually cause the tableView to respond.
Here is some of the code from photoViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.photoCount = 0;
self.timestamp = [[NSDate date] timeIntervalSince1970];
self.photos = [[NSMutableArray alloc] initWithCapacity:5];
self.photosData = [[NSMutableArray alloc] initWithCapacity:5];
self.uploadingCount = 0;
UINib *customCell = [UINib nibWithNibName:#"CustomTableCell" bundle:[NSBundle mainBundle]];
[self.tableView registerNib:customCell forCellReuseIdentifier:#"customCell"];
self.tableView.separatorColor = [UIColor clearColor];
NSLog(#"%#", self);
}
and also the addPhotoFromData method:
- (void)addPhotoFromData:(NSDictionary *)info
{
[self.photos addObject:info];
NSLog(#"%#", self.photos); //Doesn't add "info" and does not return anything when later called from other methods.
[self.tableView reloadData]; //Doesn't work
Everything was working before I add in the UINavigationController. I'm completely lost.
EDIT: After some more debugging attempts, I have discovered that the view is not loaded when addPhotoFromData is called. viewDidLoad is called afterwords. Is there a way to delay method calls?
Any reason you can't have the PhotoViewController call addPhotoFromData: inside the viewDidLoad method? You can always access properties of the app delegate from the view controller:
YourAppDelegateType * delegate = [UIApplication sharedApplication].delegate;
[self addPhotoFromData:delegate.info];

ios sdk attach and play video file in view controller before attaching tab bar to main window

I have an non ARC project. So i am maintaining its memory management. It has an tabbar and navigation controller.In that on launch before showing tab bar i have to show an launch video of 5 sec kind of thing. so i have two question
Best and easy way to show an view controller before attaching tab bar controller to main window without leaks.Following is my current technique and code but code analyzer is showing me potential leaks in my video controller.
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
UIViewController *viewController = [[MyViewController alloc] initWithNibName:#"MyViewController" bundle:nil] ;
myNavigationController = [ [ UINavigationController alloc ] initWithRootViewController: viewController ];
[viewController release];
NSMutableArray *viewControllers;
viewControllers = [[NSMutableArray alloc] init];
[viewControllers addObject: myNavigationController]; //Tab 1
myNavigationController release];
// ADD Tab 2 //ADD Tab 3 //ADD Tab 4
self.tabBarController = [[[UITabBarController alloc] init] autorelease];
self.tabBarController.viewControllers = viewControllers;
[viewControllers release];
//Add video contoller before showing tabs
self.videoController = [[VideoPlayViewController alloc] initWithNibName:#"VideoPlayViewController" bundle:nil];
[self.window addSubview:videoController.view];
[self.window makeKeyAndVisible];
Here is my Video Player controller code
- (void)viewDidLoad
{
[super viewDidLoad];
MPMoviePlayerController *moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:#"some url"];
//------ init code in between and added observer to movie playback finish callback ------
[self.view addSubview:moviePlayer.view ]; //show potential leak here if i not release moviePlayer
//[moviePlayer release]; //if i release here controller show me black window with no video playing
}
- (void) moviePlayBackDidFinish:(NSNotification*)notification {
MPMoviePlayerController *player = [notification object];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerDidExitFullscreenNotification
object:nil];
[player stop];
[player.view removeFromSuperview];
[player release]; //show incorrect decrement of reference count of an object that is not owned at this point by caller
//Fire notification to add tab bar as root view controller
}
And after video is played i get notificaton in my appdelegate and then
[videoController.view removeFromSuperview];
[self.videoController release];
self.videoController = nil;
self.window.rootViewController = self.tabBarController;
and my main app delegate dealloc as usual
- (void)dealloc {
[_window release];
[_tabBarController release];
[super dealloc];
}
i think i explained my problem correctly.Please anyone have any better way to do this.
Thanks
Declare the moviePlayer variable outside of viewDidLoad and then release it in moviePlayBackDidFinish. You're adding a reference to it and then removing only that reference. The reason you're being notified about a leak is that moviePlayer is never released - and with the current setup of your code you can't release it.
MPMoviePlayerController *moviePlayer; //keep reference to moviePlayer
- (void)viewDidLoad
{
[super viewDidLoad];
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:#"some url"];
[self.view addSubview:moviePlayer.view ];
}
- (void) moviePlayBackDidFinish:(NSNotification*)notification {
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerDidExitFullscreenNotification
object:nil];
[moviePlayer stop];
[moviePlayer.view removeFromSuperview];
[moviePlayer release];
}

ios navigation controller

I have this buttons controller with buttons xib. This buttons is included in my other views. The problem I have is button clicked navigation.
-(IBAction) gotoReport:(id) sender
{ NSLog(#"ll");
ReportStepOne *report = [[ReportStepOne alloc]init];
[self.navigationController pushViewController:report animated:YES];
[report release];
}
I could see the log message, but navigation doesn't work. I guess I should not use self?
appDelegate.H
UINavigationController *navCon;
appDelegate.M
navCon = [[UINavigationController alloc] init];
[navCon setNavigationBarHidden:YES];
Login *login = [[Login alloc] init];
[navCon pushViewController:login animated:NO];
[login release];
[window addSubview:navCon.view];
[self.window makeKeyAndVisible];
Your first example of IBAction is correct, it should pus the view. If it's not pushing, you need to check your XIB to make sure you have connected the correct button to this IBAction.
in your app delegate, do this instead:
Login *login = [[Login alloc] init];
// Make navController a property..
self.navController = [[UINavigationController alloc] initWithRootViewController:login];
//This is the key..
[[self window] setRootViewController:self.navController];
[self.navController setNavigationBarHidden:YES];
[login release];
[self.window makeKeyAndVisible];

NavigationBar not displaying properling when pushViewController

The problem is pretty simple to understand with pictures.
I have a UINavigationController that allow the user to switch between to views.
The first view contains a search bar and a table view like so :
The second is a basic view where information about the cell are display
When I click on the search bar, the navigation controller gets hidden and the search bar is now at the top.
Now, if I click on a cell, it goes to the second views, but the navigation bar is first hidden like below :
And then, it automatically appears like that :
I have tried a couple of things like show the navigation bar before pushing the next view controller but it is quite ugly..
Does anyone know how to have the show the navigation bar directly on the second view (like in the contact application)?
[UPDATE] : Code
AppDelegate.m (I'm talking about navigationcontroller2)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
FirstViewController *viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
SecondViewController *viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
viewController1.managedObjectContext = [self managedObjectContext];
viewController2.managedObjectContext = [self managedObjectContext];
viewController1.viewController2 = viewController2;
UINavigationController *navigationcontroller1 = [[UINavigationController alloc] initWithRootViewController:viewController1];
[navigationcontroller1.navigationBar setTintColor:[UIColor lightGrayColor]];
UINavigationController *navigationcontroller2 = [[UINavigationController alloc] initWithRootViewController:viewController2];
[navigationcontroller2.navigationBar setTintColor:[UIColor lightGrayColor]];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:navigationcontroller1, navigationcontroller2, nil];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
FirstView.m
- (void) searchBarTextDidBeginEditing:(UISearchBar *)theSearchBar {
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (!noResultsToDisplay) {
PinDetailsViewController *pinDetailsViewController = [[PinDetailsViewController alloc] initWithNibName:#"PinDetailsViewController" bundle:nil];
NSManagedObject *managedObject = [fetchedResultsController objectAtIndexPath:indexPath];
Pin *pin = (Pin *) managedObject;
[self.navigationItem setTitle:#"Pins"];
[self.navigationController pushViewController:pinDetailsViewController animated:YES];
[pinDetailsViewController updateWithPin:pin];
}
}
If you need anything else, just ask but I think it's all there.
Try to use this code in each viewcontroller.
- (void) viewWillAppear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:NO animated:animated];
}
- (void) viewWillDisappear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:YES animated:animated];
}
Before you push the new view controller, you should unhide the navigation bar:
[self.navigationController setNavigationBarHidden:NO animated:YES];
I had a similar problem with the position of my navbar. Mine was moving up behind the status bar, and I fixed the issue by manually setting the navbar frame:
-(void)adjustNavBarOrigin
{
CGRect r = self.navigationController.navigationBar.frame;
r.origin = CGPointMake(0, 20); // 20 is the height of the status bar
self.navigationController.navigationBar.frame = r;
}
I had to call this method in a number of places, including viewWillAppear: and didRotateFromInterfaceOrientation:, but it worked a treat :)
Hiding the UINavigationBar can disturb the properties sometimes. Try using the property alpha instead of hidden.

How to dismiss and present the same modal view controller right after?

I want to make it seem as if it was a reset button.
It would take me to my mainviewcontroller screen and then come right back.
MainViewController.m
MainViewController.h
MainViewController.xib
ViewController.xib
ViewController.m
ViewController.h
I do not understand how I am supposed to do this.....
- (IBAction)newGame:(id)sender {
[self dismissModalViewControllerAnimated:YES];
ViewController *screen = [[ViewController alloc] inittWithNibName:#"ViewController" bundle:nil];
screen.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:screen animated:YES];
}
Any ideas of how to do this?
Thanks
Do that without animation, as following.
- (IBAction)newGame:(id)sender {
[self dismissModalViewControllerAnimated:NO];
ViewController *screen = [[ViewController alloc] inittWithNibName:#"ViewController" bundle:nil];
screen.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:screen animated:NO];
}