Remove a view from TabBarController - iphone

I'm using a TabBarController to select the first view of that spec. part. From this I've to push other views which have to removed later. Example (ReviewDetailController is an UIViewController):
ReviewDetailController *ctr = [[ReviewDetailController alloc] initWithNibName:#"ReviewDetail" bundle:nil];
... do some initializing and then
self.tabBarController.selectedViewController = ctr;
[ctr release];
This works, but I find no way to go back to the previous view.
Because it is not a navigationController, I can't use pushViewController and later popViewController.
But to push and to pop is what I really need.

I don't know if I did understand this rightly, but maybe you can use this
- (void)tabBarController:(UITabBarController *)tabBarController
didSelectViewController:(UIViewController *)viewController;
Store your topfrontViewController and you can switch between them.
Remember to set the delegate.

Related

setViewControllers of UINavigationController crash app when use with animation:NO

this is working very fine:
[(UINavigationController*)viewController setViewControllers:[NSArray arrayWithObject:cvc] animated:YES];
But This cause my application to crash:
[(UINavigationController*)viewController setViewControllers:[NSArray arrayWithObject:cvc] animated:NO];
the same line I have used in else part with different viewController with animation:NO and it is working fine. Am I missing something or it is a bug?
If you are setting your view controller as rootViewController then do this
yourNavigationController=[[UINavigationController alloc]initWithRootViewController:cvc];
and then when you want to go to newViewController then use pushViewController
[self.navigationController pushViewController:yourViewObject animated:YES];
Apple has given the documentation of this function only with animation set to YES.
- (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);
// If animated is YES, then simulate a push or pop depending on whether the new top view controller was previously in the stack.
I think when you set the animation to 'No' the new top-level NavigationController has not been initialized and loaded properly until the animation is done.

App Crashes in UITabBarController delegate method

Hi
I am trying to add and remove tab bar elements dynamically. There are two arrays. One is shown first with an added tabbaritem with name "More" and other array is added to the tabbar when user presses More. User can come back to first array by pressing Less tabbaritem in second array. Problem is that when i frequently press More and Less tabbaritems in sequence More, Less, More, Less, More, Less - The app crashes after last Less. Array seems ok to me and so is tabbar controller. I am not able to figure out the problem.
Below is the code of tab bar delegate method.
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
NSLog(#"selected view controller is :%#",viewController);
if(viewController.view.tag == -1){
[self.tabBarController setViewControllers:self.level2TabBarItems animated:YES];
[self.tabBarController setSelectedIndex:0];
}else if(viewController.view.tag == -2){
[self.tabBarController setViewControllers:self.level1TabBarItems animated:YES];
[self.tabBarController setSelectedIndex:0];
}
}
Can anyone please let me know where I am doing wrong?
Best Regards
I had similar problem. I guess that you construct new instance of VC in your array, so frequently switching more/less causes calling method from the old instance (is not replaced yet at that moment).
Unfortunatelly setViewControllers method (as documentation say) automatically remove old view controllers calling dealloc and it seems that there is no other way to reuse them.
In your case you can try to disable selecting tabs until tabBarController:didSelectViewController: execute implementing (I didn't test it):
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
self.selectLock = YES;
// your code
self.selectLock = NO;
}
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
return !self.selectLock;
}
Make comment NSLog here. This is not proper format to print this.
May be your array's are empty. Try to set a breakpoint and you will find the solution which line is causing the crash.
I think Both if and else if are not satisfied with this condition
Just Check your Tag with this NSLog(#"%d",viewController.view.tag);

self.tabBarController.selectedIndex not calling viewDidAppear:YES

In a tabbar view when I call the tab to load useing self.tabBarController.selectedIndex the viewWillAppear is not called If i am been to the tab before hand is there a way to force the view to reload.
self.tabBarController.selectedIndex = 3;
[self.tabBarController.selectedViewController viewDidAppear:YES];
I was also thanking of dumping memory ever time i change tab's and that way when i get back to that view it reloads from the database.
you can implement
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
in the UITabBarControllerDelegate (probably your app delegate). Then in there you can manually call the methods you want on whichever index's viewController you selected.

Dismiss ModalViewController from another viewController in subview

I've got a view called A open with presentModalViewController Method, inside this view I loaded secondary view using:
new_view = [[new_websongs alloc] initWithNibName:#"new_websongs" bundle:nil];
[mysubview addSubview:new_view.view];
ok, to here it's ok but now I need to dismiss the first view "A" calling a method [self dismissModalViewControllerAnimated:YES] situated if first "A" viewController from secondary view controller (new_view) but not work! the code is:
self.Aviewcontroller = [[Aview alloc] init];
[Aviewcontroller dismissModalViewControllerAnimated:YES];
[Aviewcontroller release];
Please help ME!!!!
Thanks
Did u try [self.parentViewController dismissModalViewControllerAnimated:YES];
You have a logical problem. Start reading View Controller Programming Guide for iOS
The view controller that present an modal view controller must dismiss it or the modal view controller must dismiss it self
Totally agree with other answers; think logically about the order of view controller order and type. So think about which controllers are shown modally, and those shown via a navigation controller.
You can of course set a number of view controllers with:
- (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated
without animation, then when required call say:
- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated
to show a specified view controller further up your stack of view controllers.
Hope this helps think about what you need to do? It's often a good idea to think about the order and type of view controllers in your app's interface in a separate project - where you can try it out on the device itself.
try this it should work
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
This works if you are presenting a modal view from a UISplitViewController. It can also be applied in so many other ways...
First, create an instance in your .h file for your appDelegate, (AppDelegate_iPad *appDelegate) then put this in your viewDidLoad or comparable method:
ipadDelegate = (AppDelegate_iPad *)[[UIApplication sharedApplication] delegate];
Now, present the first modal view like this:
YOURVC *vc = [[YOURVC alloc] initWithNibName:#"YOURVC" bundle:nil];
[ipadDelegate.splitViewController presentModalViewController:vc animated:YES];
[vc release];
Say you have a subview, like a UITableView, and want to dismiss the modal from the didSelectRowAtIndexPath. All you have to do to dismiss your modal with a subview is create another ipadDelegate instance inside your subview's .h (if needed), reference the [[UIApplication sharedApplication] delegate] again, and dismiss:
[ipadAppDelegate.splitViewController dismissModalViewControllerAnimated:YES];
Essentially, as long-winded as it may be, use your appDelegate's controller to present and dismiss the the modal if you need to maintain a persistent reference to the presentingViewController...because all the things above just don't work in my case.
If you're presenting with your ipadDelegate, make sure you check the mode of presentation in your MainWindow_iPad.xib. Your "Transition Style" should be "Cover Vertical" and "Presentation" should be "Current Context" or your modal may present behind other views.

UINavigationController and viewWillDisappear

So I have a UINavController in my app and am trying to execute a method when the user presses the back button. I have searched everywhere and can only find bits and pieces that don't really make sense out of context.
Is there a way to implement some sort of check that catches when the user presses the back button to dismiss the current view? (the viewWillDisappear method for the view being popped never gets called for some reason. I did read that it doesn't unless you forward that call?) Does that sound right, and does anyone have any ideas or suggestions? Thanks in advance.
Take a look at the UINavigationControllerDelegate. There are the only two methods that get called when a UIViewController is pushed to the navigation controller stack. Similarly, if one is being pushed then something probably was just popped. This is what I did to call viewDidDisappear and viewWillDisappear.
# pragma mark - UINavigationControllerDelegate Methods
- (void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
static UIViewController *vcPointer = nil;
// If the previous view controller is still around then let's send a viewWillDisappear message
if (vcPointer != nil) {
if ([vcPointer respondsToSelector:#selector(viewWillDisappear:)]) {
[vcPointer viewWillDisappear:animated];
}
}
// Keep track of a pointer to the current viewController
vcPointer = viewController;
[viewController viewWillAppear:animated];
}
This code keeps a pointer reference to the last view controller that was pushed so that once we push another one we can pop the last one (if it still exists).
AFAIK, if you add a UINavigationController to a UIView via code, it won't send those messages to it's subviews by default. It will only do this if the UINavigationController received these calls itself. Maybe this is your problem (I don't know your view setup).
So, when adding the view of the UINavigationController, be sure to manually send it these messages.
UINavigationController *navigationController = [UINavigationController alloc] initWithRootViewController:rootViewController];
[navigationController viewWillAppear:NO];
[aView addSubview:navigationController.view];
[navigationController viewDidAppear:NO];
At least, this is what I found during development. Been searching for this for a long time and I still don't understand the rationale behind it.
You can always hide the default back navigation button and create your own with its own method to be called when pressed.
Execute whatever code you want there then pop the view.
I used this solution:
Add a custom button on the left side in the navigation bar
Let that button activate a custom method.
Disadvantage of this workaround: you will lose that nice arrow shaped "back" button. That can be solved as well with a custom image.
So here is my code.
Put this in your viewDidLoad:
// LeftButton in Navigation Bar
UIBarButtonItem *leftBarButton = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStylePlain target:self action:#selector(backButtonPushed:)];
self.navigationItem.leftBarButtonItem = leftBarButton;
[leftBarButton release];
Then add this method in the same .m file:
- (void) backButtonPushed: (id)sender {
// do what you want to do
}
dont forget in the .h file
- (void) backButtonPushed: (id)sender;
The viewWillDisappear & viewDidDisappear is called when a controller is popped or dismissed. The function is called on the fore-front view controller not on the UINavigationController itself. Did you possibly subclass and forget to call the super on something?