UIViewController presentModalViewController: animated: doing nothing? - iphone

I recently started a project, using Apple's Utility Application example project. In the example project, there's an info button that shows an instance of FlipSideView. If you know the Weather.app, you know what the button acts like.
I then changed the MainWindow.xib to contain a scrollview in the middle of the window and a page-control view at the bottom of the window (again, like the Weather.app). The scrollview gets filled with instances of MainView. When I then clicked the info button, the FlipSideView would show, but only in the area that was previously filled by the MainView instance – this means that the page-control view on the bottom of the page still showed when the FlipSideView instance got loaded.
So, I thought that I would simply add a UIViewController for the top-most window, which is the one declared inside the AppDelegate created along side with the project. So, I created a subclass of UIViewController, put an instance of it inside MainWindow.xib and connected it's view outlet to the UIWindow declared as window inside the app delegate. I also changed the button's action, so that it know sends a message to the MainWindowController instance. The message does get sent (I checked with NSLog() statements), but the FlipSideView doesn't get shown. Here's the relevant (?) code:
FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:#"FlipsideView" bundle:nil];
controller.delegate = self;
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
[controller release];
Why's this not working from inside of MainWindowController, but the exact same code is working from inside of MainViewController? I've uploaded the entire project here for you to be able to see the whole thing.
Thanks for help!
-- Ry
EDIT: I think it might be related to me attaching the UIViewController's view outlet to an UIWindow instance. I now connect it to a UIView, and it's working perfectly well.

For the record, the answer has been added in the question. Ryyst said:
I think it might be related to me
attaching the UIViewController's view
outlet to an UIWindow instance. I now
connect it to a UIView, and it's
working perfectly well.

Related

NavigationController and Modal Views

I am a newbie to iOS world and have started building custom code on top of a templated code.
So excuse me for the obvious.
The View chain starts with a MainWindow.xib which contains a App Delegate Object, a Window Object and Application ViewController. I dont understand why those objects are needed over there. But what I understand, I need to mention starting ViewController in the "Nib Name" Property to initiate my custom View Controller (called "EmptyViewController"). Its a dummy view controller, just there to avoid crash to happen as a result of missing valid viewcontroller.
I initiate a separate Modal View Controller(MainViewController) inside didFinishLaunchingWithOptions.
Code for initiating modal View Controller --
self.window.rootViewController = self.viewController;
mainView = [[MainViewController alloc] initWithNibName:#"MainViewController" bundle:nil];
// present the viewcontroller
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:mainView];
[self.viewController presentModalViewController:navController animated:NO];
// release it, because it's retained as modalViewController
[navController release];
I do not put this MainViewController inside MainWindow.xib as I want to have navigation at the root of MainViewController.
Inside MainViewController, I push HelpViewController when "help" button is pressed.
But HelpViewController does not show any navigation bar. I do not understand why?
Code for Pushing Navigation bar --
HelpViewController *helpVC = [[HelpViewController alloc] init];
[self.navigationController pushViewController:helpVC animated:YES];
[helpVC release];
So I would like to understand --
1) Why is MainWindow.xib needed? Can I remove it? (Note: I tried to remove it, but then I get blank screen)
1.a) Why are all the controls/objects App Delegate Object, a Window Object and Application ViewController objects needed?
2) Why doesnt HelpViewController show Navigation bar?
3) Another thing I noticed, if I say self.presentingViewController, EmptyViewController handle is returned while popViewController returns me back to MainViewController.
Thanks
The App Delegate simply implements some app-level 'callbacks' by which iOS communicates with your own code. In main.m you can see how iOS is told which of your classes implements UIApplicationDelegate. iOS creates an instance of this class and call these delegate methods ('callback') whenever appropriate (e.g. when the app goes to background).
The Window is something iOS provides, your app needs to tell what to display on it. And, as you saw, this is usually done in didFinishLaunchingWithOptions (which is called by iOS to inform your app things are ready to get started).
A View Controller is a class that handles states of stuff you show on the Window. You don't show stuff directly on the Window, but instead use Views. Every View Controller has a View with UI elements.
The XIB or NIB is a UI description/layout file. A XIB and View are linked together; you need to tell the XIB to which View Controller member (e.g. a UILabel) a UI element belongs, and you tell the XIB which View Controller method to call on a certain UI event (e.g. user taps on a button).
These are the basics. I'm aware it does not answer all your questions; I suggest you read the very good Apple documentation. Don't try to understand everything immediately as things, as you're experiencing, indeed can seem illogical at start.

I can make UINavigationController load only at 2nd level, not at Root View Controller

I tried looking for a similar problem but I could not find a similar question.
I am loading a UINavigationController in a UIView which is not (as in most examples) the MainWindow.
I created one new .xib called DocumentsViewController which is subclass of UIView (it has the related .m and .h files). And I created a DocumentsRootViewController.xib, which is a subclass of UITableViewController, which is supposed to be the UINavigationController's RootViewController.
I moved to DocumentsViewController and added a UINavigationController object in Interface Builder. Then I went to code, and added it as in IBOutlet, and connected it to the object.
In the ViewDidLoad, I execute the following lines:
DocumentsRootViewController *rootViewController = [[[DocumentsRootViewController alloc] init] autorelease];
rootViewController.title = #"Documents";
[navigationControllerDocuments initWithRootViewController:rootViewController];
[self.view addSubview:navigationControllerDocuments.view];
It shows the table as intended, but it shows a "Back" button to the "Root View Controller" (as in picture below).
Why? Shouldn't it already know that the rootviewcontroller has been set?
Thank you in advance to the ones that clarify this doubt
Giovanni
When you add the UINavigationController via the Nib it actually creates an instance of a UINavigationController inside the nib file with a default RootViewController set (of type UIViewController) and with a default title of RootViewController.
When you load the nib, this object is being created as part of loading the nib (i.e when you initialise DocumentsViewController) - so the navigationControllerDocuments outlet is already initialised as a UINavigationController with the default ViewController already set on it.
What I think is happening is when you call 'initWithRootViewController' - you are calling this on an already initialised object - so it is running the initialisation code again - pushing the second view controller (the DocumentRootViewController) onto the stack, but the default one that was created in the nib is already there.
What you should probably do is forget about creating one in the nib and initialise the whole thing programatically.
i.e. where you do:
[navigationControllerDocuments initWithRootViewController:rootViewController];
I suggest that you do an alloc and init instead:
[[navigationControllerDocuments alloc] initWithRootViewController:rootViewController];
Since you are doing this you really don't need to have the navigation controller added to the nib so if this works you should remove it from the nib since you are replacing it with this one in code.

Hoew to implement Navigation on button click

my project first used the Three20 frame work for handling navigation.But due to some problems i ha to remove the three20 part.So im redesigning my app.
what im trying to do is show a detail view when user touches a button.I created a new mainwindow as there was none earlier.It does not have a navigation controller.
i used
DetailViewController *detailViewController=[[DetailViewController alloc] init];
[self.navigationController pushviewController:detailviewController animated:YES]
in the buttos touch up event.
but when i run the app nothings hapens on button touch.No warnings or errors are shown.
Ive done this in other apps but it just doesnt work here.
Since you are not using a UINavigationController, the navigationController property of the your UIViewController will remain nil. "Compile-wise" there's no problem, since the property exists, but the compiler does not know the property will remain nil, hence no warnings/errors are shown.
Sending a message to a nil object is allowed in Objective-C, hence the code doesn't crash and does nothing when being run.
If you want to get your code up & running, you'll need to put the root UIViewController in a UINavigationController. Once the UIViewController is shown in a UINavigationController, the property will be set to the UINavigationController automatically.
Edit: You could use something like this, instead of showing someController, "encapsulate" it in a UINavigationController and show that controller.
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:someController];

UIViewTableCell didSelectRowAtIndexPath is calling but not pushing a view controller

so im having a UIViewController view with a UITableView.
So the UIViewController class name is SelectionScreen.
The UITableView class name is SelectionScreenTable.
Picture:
http://img717.imageshack.us/i/screenshot20100609atpm0.png/
I have declared a UITableView *selectionTable in SelectionScreen class and connected it to the xib file of the SelectionScreen
what the problem is , is that when i click a row in the table,it stays selected as highlighted blue, it calls the didSelectRowAtIndexPath (checked with NSLog) but not pushing a new view which is called(GraphView).
This is the code which i use to call the new controller WHICH WORKS with a normal button
GraphView *aSelectionScreenViewController = [[GraphView alloc]
initWithNibName:#"GraphView"
bundle:nil];
[self presentModalViewController:aSelectionScreenViewController animated: YES];
[aSelectionScreenViewController release];
I searched around and found that I need to set a delegate for the table in the UITableView class itself on the viewload
tableview.delegate = self;
or
self.tableview.delegate = self;
But it was not working. the controller was still not being pushed, and yes i have checked the controller is not nil as i tried it with a simple button.
So i was thinking whether i should set the delegate of the UITableView at the UIViewController instead, so i tried this code
selectionTable.delegate = selectionTable.self;
but obviously it did not work =\, it messed up the whole UITableView and caused all the cells to be its predefined settings.
So does anybody have any idea on how i can get it to work.
It's a bit hard to get the full picture here, but I can try some hints.
The outlets seem to be correctly connected from the screenshot, although Selection Screen Table could probably be called Selection Screen Table Controller and the class name should be SelectionScreenTableController for less confusion.
I think the problem could be that the method presentModalViewController: must be called on an active view controller to work.
From what I can tell you have three view controllers, a SelectionScreenTableController, a GraphViewController, and then there must also be some kind of main controller, probably SelectionScreenController.
The SelectionScreenController is the active view controller, so that must be the one to have sent the presentModalViewController: message.
There are several ways you could solve this. The quick fix would be to make an outlet in SelectionScreenTableController called selectionScreenController and link it to File's Owner in the nib file (assuming your SelectionScreen class is in fact a view controller), then call:
[selectionScreenController
presentModalViewController:aSelectionScreenViewController
animated: YES];
instead in your current listing of didSelectRowAtIndexPath:
Hey guys, i solved it, in the screenshot
http://img717.imageshack.us/i/screenshot20100609atpm0.png/
The SelectionScreenTable controller in the XIB of SelectionScreen, the view outlet was not connected to the XIB in the SelectionScreen XIB, so i guess it wasn't properly configured.
i solved it instead of using
presentModalViewController.
i used an animation to bring in the view instead
More info in the link below
http://www.iphonedevsdk.com/forum/iphone-sdk-development/13427-uiview-slide-transition.html

Pushing View from UITableView Problem

Basically, what I want is to be able to press a record in a table, and have it push to another view.
To do this, I created a nib file and a UIViewController subclass (for the "pushed" view). I set the nib file's "File Owner" to be the controller I created. EDIT: I also then set the "view" field of the controller to be the View. Then, in the view controller of the table that will push that view, I set the didSelectRowIndexAtPath: method to include the following:
SearchTableController *vc = [[SearchTableController alloc] initWithNibName:#"SearchTable" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:vc animated:YES];
[vc release];
(where "SearchTableController" is the name of the UIViewController subclass and "SearchTable" is the name of the nib file)
However, when I run this code and click on the record, nothing happens- the app doesn't crash, but the view doesn't get pushed. The code is getting run, because it works when I NSLog(), but it doesn't seem to be pushing the view.
Thanks for any help in advance.
You are really close, but did you tie the view in the nib file to the view field of the view controller?
EDIT: So the view is connected, and your code looks just fine. I just pulled a piece of my own code:
// show theme settings
ThemeController * theme = [[[ThemeController alloc]
initWithStyle:UITableViewStyleGrouped] autorelease];
[[self navigationController] pushViewController:theme animated:YES];
Have you checked if self.navigationController is non-nil?
Couple of things I'd try at this point:
just hard-code the view to come up as the root view, verify it works
put a couple of NSLogs in the viewWillLoad, viewDidLoad, viewWillAppear in the client view controller
Best of luck.