I am making demo in which I have to remove some of viewControllers from the NavigationController, and for that I have implemented below code but it give me issue.
I have pushed VC1,VC2,VC3 and now I want to push VC4 and remove VC2...
ViewController4 *VC4=[[ViewController4 alloc]initWithNibName:#"ViewController4" bundle:nil];
[self.navigationController pushViewController:VC4 animated:YES];
NSMutableArray *viewControllers = [NSMutableArray arrayWithArray:[[self navigationController] viewControllers]];
for(UIViewController *objVC in viewControllers)
{
if([objVC isKindOfClass:[ViewController2 class]])
{
[viewControllers removeObjectIdenticalTo:objVC];
}
}
self.navigationController.viewControllers =viewControllers ;
This code works fine with iOS8 but in iOS7 with VC2 also VC3 removes automatically when I press the back button in VC4.
Even if I put below code the controller automatically removes from stack.
ViewController4 *VC4=[[ViewController4 alloc]initWithNibName:#"ViewController4" bundle:nil];
[self.navigationController pushViewController:VC4 animated:YES];
NSMutableArray *viewControllers = [NSMutableArray arrayWithArray:[[self navigationController] viewControllers]];
self.navigationController.viewControllers =viewControllers ;
Here is the fix, working fine in iOS7 and iOS8:
NSMutableArray *viewControllers = [NSMutableArray arrayWithArray:[[self navigationController] viewControllers]];
// Find the things to remove
NSMutableArray *toDelete = [NSMutableArray array];
for(UIViewController *objVC in viewControllers)
{
if([objVC isKindOfClass:[ViewController2 class]])
{
[toDelete addObject:objVC];
}
}
[viewControllers removeObjectsInArray:toDelete];
self.navigationController.viewControllers =viewControllers ;
ViewController4 *VC4=[[ViewController4 alloc]initWithNibName:#"ViewController4" bundle:nil];
[self.navigationController pushViewController:VC4 animated:YES];
Related
I have implemented MFSideMenu in my project .It works great, but now i want to implement back button facility to every view.
I try this but not working:
NSArray *array = [self.navigationController viewControllers];
[self.navigationController popToViewController:[array objectAtIndex:1] animated:YES];
Here is the Solution
HomeView *Home = [[HomeView alloc]initWithNibName:#"HomeView" bundle:nil];
NSArray *controllers = [NSArray arrayWithObject:Home];
self.navigationController.viewControllers = controllers;
There are three controllers here, AViewController, BViewController, CViewController,
the first step: AViewController present to BViewController;
BViewController *BVC = [[BViewController alloc]init];
[self presentViewController:BVC animated:YES completion:nil];
The second step: BViewController push to CViewController;
CViewController *CVC = [[CViewController alloc]init];
UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:CVC];
[self.navigationController pushViewController:nav animated:YES];
Now, if I want to go back from CViewController to AViewController, what code should I write?
Just use this code:
self.dismissViewControllerAnimated(true, completion: nil)
to dismiss C ViewController, because C ViewController is now on the Navigation Stack. A present a navigation controller that contain B ViewController. B ViewController push C ViewController, so C is still in Navigation Controller.
You can look at my project here:
https://github.com/khuong291/TestTransition
You should present BViewController like this:
BViewController *BVC = [[BViewController alloc]init];
UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:BVC];
//Setting For Transparent
nav.providesPresentationContextTransitionStyle = YES;
nav.definesPresentationContext = YES;
nav.modalPresentationStyle = UIModalPresentationOverCurrentContext;
[self presentViewController:nav animated:YES completion:nil];
and in BViewController implement:
- (void)viewWillDisappear:(BOOL)animated {
[self.navigationController setNavigationBarHidden:YES];
}
- (void)viewWillDisappear:(BOOL)animated{
[self.navigationController setNavigationBarHidden:NO];
}
And you can push to CViewController:
CViewController *CVC = [[CViewController alloc]init];
[self.navigationController pushViewController:CVC animated:YES];
And when you want back to A. Simple call it in C:
[self dismissViewControllerAnimated:YES completion:nil];
Usually I can replace my detail view of splitview by this code in Objective-C:
[self.splitViewController viewWillDisappear:YES];
NSMutableArray *viewControllerArray=[[NSMutableArray alloc] initWithArray:[[self.splitViewController.viewControllers objectAtIndex:1] viewControllers]];
[viewControllerArray removeLastObject];
[viewControllerArray addObject:self.detailViewController];
[[self.splitViewController.viewControllers objectAtIndex:1] setViewControllers:viewControllerArray animated:NO];
[self.splitViewController viewWillAppear:YES];
Try to rewrite it in Swift, but I even can't get the viewControllers in this code:
NSMutableArray *viewControllerArray=[[NSMutableArray alloc] initWithArray:[[self.splitViewController.viewControllers objectAtIndex:1] viewControllers]];
Swift:
let test: UIViewController = (self.splitViewController?.viewControllers[1])!
It should have test.viewControllers , but it doesn't as seen in below pic
Does Swift handle the replace in splitview in different way?
This works for me but I am not sure if this is the best practice:
let detailViewController = self.storyboard?.instantiateViewControllerWithIdentifier("DetailNavigationViewController") as! UINavigationController
self.splitViewController?.viewControllers[1] = detailViewController
Only need to get the desired viewController and assign it to index 1 of splitViewController
Next button is not working. It throws an error Application tried to present modally an active controller What should i do to enumerate through array of ViewControllers when i press next button. I have read many threads regarding the same problem but could not figure out the solution. Thanks in advance!
.h file
#property(nonatomic, strong) NSMutableArray *tab;
.m file
- (IBAction)newTab:(id)sender {
UIStoryboard *st = [UIStoryboard storyboardWithName:[[NSBundle mainBundle].infoDictionary objectForKey:#"UIMainStoryboardFile"] bundle:[NSBundle mainBundle]];
myViewController *newTab = [st instantiateViewControllerWithIdentifier:#"myViewController"];
if (![newTab isBeingPresented]) {
[self presentViewController:newTab animated:YES completion:nil];
[tab addObject:newTab];
}
}
- (IBAction)next:(id)sender {
[tab enumerateObjectsUsingBlock:^(id object, NSUInteger idx, BOOL *stop) {
[self presentViewController:tab[idx] animated:YES completion:nil];
}]; }
- (IBAction)prev:(id)sender {
for (i=[tab count]; i>0; i--) {
if (![self isBeingDismissed]){
[tab[i-1] dismissViewControllerAnimated:YES completion:nil];
;
}}}
You can enumerate the ViewControllers present in stack
NSArray * controllerArray = [[self navigationController] viewControllers];
for (UIViewController *controller in controllerArray){
//Code here.. e.g. print their titles to see the array setup;
NSLog(#"%#",controller.title);
if ([controller.title isEqual:#"Title1"]) {
[self.navigationController popToViewController:controller animated:YES];
}
}
On selecting Next button enumerate through the Views present in stack and check for the title and do that specific operation needed for that view. Above i have added the code to popViewController if the title matches.
Hope it helps.
I am replacing a view inside a navigation controller with the setViewControllers-method.
But i dont like the look of the transition. How can i set the animation-style when using the following code ?
UIViewController *newVC = [self.storyboard instantiateViewControllerWithIdentifier:#"SuccessScreen"];
NSMutableArray *viewControllers = [NSMutableArray arrayWithArray:[[self navigationController] viewControllers]];
[viewControllers removeLastObject];
[viewControllers addObject:newVC];
[[self navigationController] setViewControllers:viewControllers animated:YES];
Something like
CATransition *yourAnimation=...;
[self.navigationController.view.layer addAnimation:yourAnimation forKey:nil]
[[self navigationController] setViewControllers:viewControllers animated:NO];