a sub viewcontroller notify the root viewcontroller to load another sub viewcontroller - iphone

I have a project in which the root viewcontroller call multi viewcontrollers. There is button on a sub viewcontroller's view, when I press the button, I hope it notify the root view controller to load another sub viewcontroller.
//the function in this viewcontroller
-(IBAction)submitButtonPressed:(id)sender;
{
[self.parentViewController notifyLoadAnotherViewContrller ] ;
}
//the function in root viewcontroller
-(void) notifyLoadAnotherViewContrller
{
Submit *tController = [[AnotherViewController alloc] initWithNibName: #"AnotherViewController" bundle:nil];
self.vanotherViewController = tController;
[tController release];
[self.view insertSubview:tController.view atIndex:10];
}
but this does not works
I set the breakpoint in function -(void) notifyLoadAnotherViewContrller
it does not work I checked the function name, no problem.
What is reason I am doing wrong?
Welcome any comment
Best Regards
interdev

So some standard debugging... Set a breakpoint in submitButtonPressed: to make sure your IBAction is properly connected. Examine parentViewController to make sure it's what you expect.
Since the method is not getting called, then your button is either not connected in Interface Builder or your parentViewController is nil, which will silently ignore the method call.

Related

iPhone multiple view flow question

I have a root view controller which contains an outlet for my login view controller. the root view should control the flow to the next view, yet my login view has the button to continue. how would I set the button's touch up inside to the IBAction in my root controller?
One method I have though of was keep a pointer to the root class where I create the login class (new code is commented out):
// RootViewController.m
- (void)viewDidLoad {
LoginViewController *loginController =
[[LoginViewController alloc]initWithNibName:#"LoginView" bundle:nil];
self.loginViewController = loginController;
//loginViewController.parent = self;
[self.view insertSubview:loginController.view atIndex:0];
[loginController release];
[super viewDidLoad];
}
- (IBAction)loginPressed: (id)sender
{
self.loginViewController.loginButton.enabled = NO; //yea... doesnt work
}
So in IB I add a UIViewController to the Nib and give it parent as an outlet, and then assign button's touch up inside event to loginPressed which is defined in the root controller (parent)... this didnt work so well explicitly refering to the controls from self.loginViewController in the RootViewController.
is there a correct way to do this.
-frustrated c++ / c# / java coder
Have you considered presenting the loginView modally? Then you can pop the view and be back at the rootViewController and move on from there.
Create the button pressed method outlet in the same class as that XIB and hook it up. I assume your login view is created by the root controller... create an assign property for the root view on the login view, and then assign the root controller to that when creating the login view. Then, in the login view's method for "button pressed" you can reference the root view controller. Spelled out:
in LoginController's .h file:
#property (nonatomic, assign) RootViewController* rvc;
in LoginController's .m file:
#synthesize rvc;
in Root View Controller's "make the login controller code", after you've initialized it but before you've presented it:
[loginController setRvc:self];
in your LoginController's button touched method:
[[self rvc] whateverMethodThatDoesLoginStuff];
This way you have your path between when the user presses the button and your "do-login" code.
You can have a loginViewController as an IBOutlet, connect its action 'touch up inside' to -loginPressed: of file owner.
Or you can alloc and init your controller in -viewDidLoad programmatically all by yourself, and set the action programmatically as well.
But what you did seems to mix the two ways.

Calling a View's method from its own View Controller, Not Working

I have a View Controller calling a method in its own view called closeMenu. closeMenu as seen below remove's a UIImageView called menu from the superView and sets it equal to nil. The method works when called from within the view but not when called from the View Controller
When calling the method, the view controller sees the UIImageView 'menu' as nil even though it is exists.
Any ideas on how to give the view controller the ability to remove menu from the superview and set it equal to nil?
View Controller:
loadview {
View *mainView = [[View alloc] initWithFrame:CGRectMake(0,0,320,480)];
self.view = mainView;
[mainView release];
}
//Call closeMenu in View
[(View *)self.view closeMenu];
View:
menu = [[UIImageView alloc] initWithImage:image];
[self addSubview:menu];
-(void)closeMenu {
NSLog(#"%#", menu); //Displays: (null), only when called by controller
if( menu != nil) {
[menu removeFromSuperview];
self.menu = nil;
}
}
When I create a button instance in the view with an action directed at the closeMenu method it works just fine.
Is menu an outlet? If so, is it hooked up in IB? Have you loaded the nib where it's hooked up?
If not, where are you assigning to it? Is the controller giving the view its menu? If that's the case, has that happened yet? If the view creates or loads its own menu view, has that happened yet, if at all?
Be assured that 'where' you call -closeMenu from makes no difference whatsoever. If your log statement prints null then your menu variable is null. This doesn't mean you haven't got an 'open' instance - just that your menu variable doesn't point to it.
You would need to post some more code for anyone to work out why this is happening as you have an error elsewhere in your code.

ipad - dismissing a UIPopoverController

I have a button inside the content of a UIPopoverController. This button runs a method called myAction.
MyAction has the form
- (void) myAction:(id)sender
so, myAction receives the id of the caller button.
Now, inside this method I would like to dismiss the UIPopoverController, but the only thing I have is the ID of the caller button. Remember that the button is inside the UIPopoverController.
Is there a way to discover the ID of the UIPopoverController, given the button ID I already have?
thanks.
Unfortunately no. At least, not within the standard practices. You might be able to travel up the responder stack to find it, but it's a hack, it's buggy, and it's really, really messy.
If you want to dismiss a popover by pushing a button, some place relevant should keep a reference to the popover. Usually that would be the owner of the popover (not the controller showed within the popover). When the button is pressed, it can send a message to the owner controller, which can then dismiss the popover.
You might be tempted to have the controller displayed inside of the popover be the owner of its own popover, but coding this way is brittle, can get messy (again), and may result in retain loops so that neither ever gets released.
You can access the presenting popoverController by accessing "popoverController" with KVC.
[[self valueForKey:#"popoverController"] dismissPopoverAnimated:YES]
I have this working, and I do not think it is a hack. I have a standard split view iPad app. I then added a method on my detail controller (the owner of the pop over) to handle the dismissal.
On the standard split view architechture, both the root and detail view controllers are available via the app delegate. So I bound a button click inside the pop over to call a method which gets the app delegate. From there I call the method on the detail controller to dismiss the pop over.
This is the code for the method on the View Controller that is displayed inside the popover:
- (void) exitView: (id)sender {
MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate.detailViewController exitDrill];
}
Then the simple method to dismiss on the Detail View Controller:
- (void) exitDrill {
if(dtController != nil){
[dtController dismissPopoverAnimated: YES];
[dtController release];
}
}
I like the ability to do this because it give me a way to show a user how they can exit a pop over. This may not be necessary in future versions of the app; for right now, while this paradigm is still new to the platform, I prefer to let the users gexit a display in a couple fo different ways to make sure I minimize frustration.
As Ed Marty already wrote
If you want to dismiss a popover by pushing a button, some place relevant should keep a reference to the popover
This is very true; however, when showing a UIPopoverController, the class opening the popovercontroller keeps this resource already. So, what you could do is to use this class as the delegate class for your Popover Controller.
To do so, you could do the following, which I use in my code.
In the class opening the popover, this is my code:
- (void)showInformationForView:(Booking*)booking frame:(CGRect)rect
{
BookingDetailsViewController *bookingView = [[BookingDetailsViewController alloc] initWithStyle:UITableViewStyleGrouped booking:booking];
[bookingView setDelegate:self];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:bookingView];
self.popController = [[UIPopoverController alloc] initWithContentViewController:navController];
[self.popController setDelegate:self];
[self.popController setPopoverContentSize:CGSizeMake(320, 320)];
rect.size.width = 0;
[self.popController presentPopoverFromRect:rect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
}
- (void)dismissPopoverAnimated:(BOOL)animated
{
[self.popController dismissPopoverAnimated:animated];
}
So what I am doing here is creating a UINavigationController and setting a BookingDetailsViewController as its rootViewController. Then I am also adding the current class as delegate to this BookingDetailsViewController.
The second thing I added is a dismissal method called dismissPopoverAnimated:animated.
In my BookingDetailsViewController.h I added the following code:
[...]
#property (nonatomic, strong) id delegate;
[...]
And in my BookingDetailsViewController.m I added this code:
[...]
#synthesize delegate = _delegate;
- (void)viewDidLoad
{
UIBarButtonItem *closeButton = [[UIBarButtonItem alloc] initWithTitle:#"Close" style:UIBarButtonItemStylePlain target:self action:#selector(closeView)];
[self.navigationItem setRightBarButtonItem:closeButton];
[super viewDidLoad];
}
- (void)closeView
{
if ([self.delegate respondsToSelector:#selector(dismissPopoverAnimated:)]) {
[self.delegate dismissPopoverAnimated:YES];
}
else {
NSLog(#"Cannot close the view, nu such dismiss method");
}
}
[...]
What happens is that when the "Close" button in the UINavigationController is pressed, the method closeView is called. This method check if the delegate responds to dismissPopoverAnimated:animated and if so, it calls it. If it does not respond to this method it will show a log message and do nothing more (so it wont crash).
I have written my code using ARC, hence there is no memory management.
I hope this helped you.

Iphone: Problem with moving back and forth between two UIViewController

Let me first describe the context of the problem. I have 2 UIViewController call AdminViewController and ButtonReorderViewController. AdminViewController contain 1 button. ButtonReorderViewController contains 1 button and 1 picture. Button in AdminViewController tie to an event call goToReorderButton. The content of goToReorderButton are below:
ButtonReorderViewController *buttonReorder = [[ButtonReorderViewController alloc] initWithNibName:#"ButtonReorderViewController" bundle:[NSBundle mainBundle]];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:buttonReorder]; //Add a Navigation Controller to the root view
[navController setNavigationBarHidden:TRUE];
buttonReorder = (ButtonReorderViewController *) navController;
[[buttonReorder view] setFrame:CGRectMake(0, -20, 320, 470)];
[self.view addSubview:buttonReorder.view];
I use UINavigationController to allow me to swipe left and right.So I am in AdminViewController, and I click on goToReorderButton, it load ButtonReorderViewController. I am able to swipe left and right (awesome !!!) So I click the button in ButtonReorderViewController call goToAdmin, simply to go back to the AdminViewController
-(void) goToAdmin{
[self.view removeFromSuperview];
}
However, as soon as I go back to AdminViewController, I cant click anything at all. The program does not seg fault, it just that I cant click the button at all. if I remove the line buttonReorder = (ButtonReorderViewController *) navController; inside goToReorderButton, then everything work fine. Any idea how to fix this?
I'm not sure that I follow you, but I think that you should use the UINavigationController methods to navigate between the view controllers:
The admin view controller should be the root view controller of the navigation controller and then you may push and pop the reorder view controller.
In app delegate (applicationDidFinishLaunching: method):
// TODO: Instantiate the adminController
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:adminController];
[window addSubview:navController.view];
In AdminViewController (button touch up inside event handler method):
// TODO: Instantiate the buttonReorder
[self.navigationController pushViewController:buttonReorder animated:YES];
In ButtonReorderViewController (back button touch up inside event handler method):
[self.navigationController popViewControllerAnimated:YES];
Of course, you have to instantiate the view controllers before using them...
Cheers,
Michael.
Sounds like the app crashed on that line you pointed out. Does the debug console output anything when it crashes?
Looks like the line buttonReorder = (ButtonReorderViewController *) navController; is failing on the cast. Are you sure ButtonReorderViewController extends UINavigationController? If not, then you can't cast it like that.
I am not sure but i think you can use PusViewController method of NavigationController to do your job.

simple question of pushViewController

messagecontroller is nothing but object of initialize nib file.
[self.navigationController pushViewController:messageController animated:YES];
this statement executes in normal condition
this statement also works on state maintainace testing ,
this line executes properly but not open new view ,why?
Calling this method call does not push a new view?
If this is the question you should ask yourself some questions:
Is self having an
UINavigationController? Make sure
self is a view controller
inside a navigation controller.
Is messageController initialized
correctly? Like this for example (if
messageController is an ivar):
messageController = [[MyViewControllerClass alloc] initWithNibName:#"MyViewControllerClassNibName" bundle:nil];