John-Lluch / SWRevealViewController

A UIViewController subclass for presenting side view controllers inspired on the FaceBook and Wunderlist apps, done right !
Other
4.52k stars 987 forks source link

Back Button Issue #582

Open amz4u2nv opened 8 years ago

amz4u2nv commented 8 years ago

Hi, I'm having some difficulties in returning back to a previous screen - Screen A is put on the nav using the code -

       BBR3DefaultNavController *navController1 = [[BBR3DefaultNavController alloc] initWithRootViewController:vc];
        [navController1 setViewControllers: @[vc] animated: YES];
        [navController1 setNavSpecs:vc];
        [navController1 setBackButton:vc];

         [self.revealViewController pushFrontViewController:navController1 animated:YES];
        //Tried the below as well but doesnt make any difference
        //[self.revealViewController setFrontViewController:navController1];
        //[self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];

In my custom nav controller BBR3DefaultNavController a function setBackButton has the following for its action -

    [self.mainController.navigationController popViewControllerAnimated:YES];
    [self dismissViewControllerAnimated:YES completion:nil]; // ios 6

    SWRevealViewController *revealViewController = self.revealViewController;
    if ( revealViewController )
    {
    }
    [self.navigationController popViewControllerAnimated:YES];

    [self.revealViewController.navigationController popViewControllerAnimated:YES];
    [self.navigationController popToRootViewControllerAnimated:YES];
    [self.mainController.revealViewController.navigationController popViewControllerAnimated:YES]; 

But none of these commands work.

Any ideas to what I'm doing wrong.

Thanks

iDevelopper commented 8 years ago

Hi @amz4u2nv ,

First, what is it for?

    [navController1 setViewControllers: @[vc] animated: YES];

and [navController1 setBackButton:vc]; You can't have a back button if your controller is not pushed by a navigation controller.

I have some ideas but explain more what you want to do exactly please! Perhaps you can send a sample or your project or some images...

amz4u2nv commented 8 years ago

Hi, Thanks for the reply, I won't be able to send across the project, as it is huge. Basically I got a side menu on the left hand side, and the front view to work ok - I wanted the side button and navigation characterics (i.e. colour of the nav bar, nav bar image) to be the same for all my view controllers hence I created a custom BBR3DefaultNavController (UINavigationController) . This all works fine

I load up the app and click on a button on the first view, this then loads the second view and has a back button on the right hand side of the nav.... when I press it I want it to go back to the first view. I've tried loads of things but can't get it to go back to the first view.

[navController1 setViewControllers: @[vc] animated: YES]; vc is the second viewcontroller that loads up when the button is clicked. [navController1 setBackButton:vc]; This tells the custom uinavigationcontroller to show the back button, vc is the second view controller.

so my custom uinavigationcontroller looks like this -

@interface BBR3DefaultNavController ()

@end

@implementation BBR3DefaultNavController
@synthesize mainController;
@synthesize currentViewController;

- (id)initWithRootViewController:(UIViewController *)rootViewController {
    NSLog(@"IN initWithRootViewController");

    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];

    self = [super initWithRootViewController:rootViewController];
    if (self) {
        [self setLeftButtonToController:rootViewController];
    }
    [self setLeftButtonToController:rootViewController];

    [self.navigationController.navigationBar
     setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor blackColor]}];
    self.navigationController.navigationBar.translucent = NO;

    self.navigationController.navigationBar.barTintColor = [UIColor whiteColor];
    self.navigationController.navigationBar.tintColor = [UIColor blackColor];

    return self;
}

- (void)setLeftButtonToController:(UIViewController *)viewController {
    //UIBarButtonItem *closeItem = [[UIBarButtonItem alloc] initWithTitle:@"Close" style:UIBarButtonItemStylePlain target:self action:@selector(dismissController)];

            UIBarButtonItem *menuButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"burger_icon.png"] style:UIBarButtonItemStylePlain target:self.revealViewController action:@selector( revealToggle: )];

    [viewController.navigationItem setLeftBarButtonItem:menuButton];
    NSLog(@"IN SETLEFTBUTTON");
}

- (void) dismissController{

}

- (void) loadView
{
    [super loadView];

    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];

  //  UIBarButtonItem *closeItem = [[UIBarButtonItem alloc] initWithTitle:@"Close" style:UIBarButtonItemStylePlain target:self action:@selector(dismissController)];

        UIBarButtonItem *menuButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"burger_icon.png"] style:UIBarButtonItemStylePlain target:self.revealViewController action:@selector( revealToggle: )];

       [self.topViewController.navigationItem setLeftBarButtonItem:menuButton];
       self.topViewController.navigationController.navigationBar.barTintColor = [UIColor whiteColor];
       self.topViewController.navigationController.navigationBar.translucent = NO;
    NSLog(@"Change bg bar colour");

    //[super loadView];

   // UIViewController * viewController = [self.navigationController.viewControllers objectAtIndex:0];
   // NSLog(@"COUNT VC %lu",[self.navigationController.viewControllers count]);
   // [viewController.view setBackgroundColor:[UIColor blueColor]];
   // [viewController.navigationItem setRightBarButtonItem:menuButton];
   // self.navigationBar.backgroundColor = [UIColor blueColor];
   // [self.presentedViewController.navigationItem setLeftBarButtonItem:menuButton];
    NSLog(@"LOADVIEW METHOD IN DEFAULT NAV CALLED");

  //  self.navigationBar.barTintColor = [UIColor whiteColor];

   // UIView *view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
    [self.topViewController.view setBackgroundColor:[UIColor blackColor]];
   // self.view = view;

   // UIStoryboard* sb = [UIStoryboard storyboardWithName:[BBR3AppDelegate storyboardName] bundle:nil];
  //

    //MainViewController *vc = (MainViewController *) [sb instantiateViewControllerWithIdentifier:@"HomePage"];
    //[self setNavSpecs:vc];
    //self.topViewController.view = vc.view;

}

- (void) setNavSpecs:(UIViewController *)viewController {
    viewController.navigationController.navigationBar.barTintColor = [UIColor whiteColor];
    viewController.navigationController.navigationBar.translucent = NO;
    viewController.navigationController.navigationBar.tintColor = [UIColor redColor];
    viewController.navigationController.navigationBar.tintColor = [UIColor blackColor];

    UIImage *img = [UIImage imageNamed:@"LogoBlack.png"];
    UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 25,  viewController.navigationController.navigationBar.frame.size.width, viewController.navigationController.navigationBar.frame.size.height-10)];

    [imgView setImage:img];
    // setContent mode aspect fit
    [imgView setContentMode:UIViewContentModeScaleAspectFit];
    [viewController.navigationController.view addSubview:imgView];

   // UIImageView *navBarHairlineImageView = [self findHairlineImageViewUnder:viewController.navigationController.navigationBar];
    //navBarHairlineImageView.hidden = YES;

}

- (void) setBackButton:(UIViewController *)viewController {
    UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Back" style: UIBarButtonItemStylePlain target:viewController action:@selector(Back:)];
    viewController.navigationItem.rightBarButtonItem = backButton;
    self.mainController = viewController;
}

- (void) setCurrentViewController:(UIViewController *)viewController {
}

- (IBAction)Back:sender
{
    NSLog(@"@BACK BUTTON PRESS");
    /*
    [self.mainController.navigationController popViewControllerAnimated:YES];
    [self dismissViewControllerAnimated:YES completion:nil]; // ios 6

    SWRevealViewController *revealViewController = self.revealViewController;
    if ( revealViewController )
    {
    }
    [self.navigationController popViewControllerAnimated:YES];

    [self.revealViewController.navigationController popViewControllerAnimated:YES];
    [self.navigationController popToRootViewControllerAnimated:YES];
    [self.mainController.revealViewController.navigationController popViewControllerAnimated:YES];
    [self.revealViewController.navigationController popViewControllerAnimated:YES];
    [self popViewControllerAnimated:YES];

    [self.revealViewController.navigationController popViewControllerAnimated:YES];
    */

  //  [self.mainController.navigationController popViewControllerAnimated:NO];
  //  [self.mainController.navigationController dismissViewControllerAnimated:YES completion:nil]; // ios 6

    SWRevealViewController *revealViewController = self.revealViewController;

    NSLog(@"Count %lu", ([self.mainController.revealViewController.navigationController.viewControllers count]));

    NSLog(@"Count %lu", ([self.mainController.navigationController.viewControllers count]));
    NSLog(@"Count %lu", ([self.revealViewController.navigationController.viewControllers count]));
    NSLog(@"Count %lu", ([self.navigationController.viewControllers count]));

    NSLog(@"Count %lu", ([revealViewController.navigationController.viewControllers count]));

    NSLog(@"Count %lu", ([self.currentViewController.navigationController.viewControllers count]));

    NSLog(@"Count %lu", ([self.currentViewController.revealViewController.navigationController.viewControllers count]));

}

- (UIImageView *)findHairlineImageViewUnder:(UIView *)view {
    if ([view isKindOfClass:UIImageView.class] && view.bounds.size.height <= 1.0) {
        return (UIImageView *)view;
    }
    for (UIView *subview in view.subviews) {
        UIImageView *imageView = [self findHairlineImageViewUnder:subview];
        if (imageView) {
            return imageView;
        }
    }
    return nil;
}

/*- (void) loadView
{
    UIBarButtonItem *closeItem = [[UIBarButtonItem alloc] initWithTitle:@"Close" style:UIBarButtonItemStylePlain target:self action:@selector(dismissController)];
    [self.rootViewController.navigationItem setRightBarButtonItem:closeItem];
}*/

@end
iDevelopper commented 8 years ago

Do you mean the first view is your frontViewController and the second one is pushed by the navigation controller?

amz4u2nv commented 8 years ago

yup

iDevelopper commented 8 years ago

I do not think it necessary to subclass UINavigatioController to add navigation characterics. It can be do just with the appearance feature with few lines of code.

amz4u2nv commented 8 years ago

but that would mean copy and pasting in each view controller the same lines.. so if had to change something for all I would have to do a lot of copying and pasting

iDevelopper commented 8 years ago

Could you post some images of your application?

amz4u2nv commented 8 years ago

simulator screen shot 18 may 2016 16 17 52 simulator screen shot 18 may 2016 16 18 39

So when I click on more on the front view I get the second view... with the back button. but the back button doesn't do anything.

iDevelopper commented 8 years ago

Then you are in a web view, exact?

amz4u2nv commented 8 years ago

yup the second view is a UIViewController with a web view

iDevelopper commented 8 years ago

Ok, when you are in the second view, you want the reveal button show the side menu?

amz4u2nv commented 8 years ago

yup, it should still show

iDevelopper commented 8 years ago

Ok, I'll write a sample

amz4u2nv commented 8 years ago

thank you

iDevelopper commented 8 years ago

SWWebView.zip

amz4u2nv commented 8 years ago
Thanks, that help a lot...
Sorted the issue out - Just one thing - I can see that you have to setup the background image for all the controllers you want it to show - 
So hence I used a uinavigation controller class - 
This worked out using code rather than the storyboard implementation -
in the app delegate - 

    UIStoryboard* sb = [UIStoryboard storyboardWithName:[BBR3AppDelegate storyboardName] bundle:nil];
    MainViewController *mainScreen = (MainViewController *) [sb instantiateViewControllerWithIdentifier:@"HomePage"];
    BBR3DefaultNavController *frontNavigationController = [[BBR3DefaultNavController alloc] initWithRootViewController:mainScreen];
    [frontNavigationController setViewControllers: @[mainScreen] animated: YES];
    [frontNavigationController setNavSpecs:mainScreen];

     UINavigationController *rearNavigationController =  (UINavigationController *) [sb instantiateViewControllerWithIdentifier:@"MainNavigation"];

    self.navController = frontNavigationController;

    SWRevealViewController *mainRevealController = [[SWRevealViewController alloc]
                                                    initWithRearViewController:rearNavigationController frontViewController:frontNavigationController];

     mainRevealController.delegate = self;
        self.window.rootViewController = mainRevealController; 

and then in the push part -

        BBR3AppDelegate *appDelegate = (BBR3AppDelegate *)[[UIApplication sharedApplication] delegate];

        UIStoryboard* sb = [UIStoryboard storyboardWithName:[BBR3AppDelegate storyboardName] bundle:nil];
        BBR3HTMLViewController *vc = (BBR3HTMLViewController *) [sb instantiateViewControllerWithIdentifier:@"WineDetailView"];
        vc.htmlContentTitle = @"About Us";
        vc.htmlContentURL = @"http://xxxxxxxxxxx-app-aboutus.html";
        vc.htmlFollowHref = YES;
        vc.navigationItem.hidesBackButton = TRUE;
        NSLog(@"HERE IN THIS SECTION");

        BBR3DefaultNavController *navController1 = appDelegate.navController;
        [navController1 pushViewController:vc animated:NO];
        [navController1 setNavSpecs:vc];
        [navController1 setBackButton:vc];

        [self.revealViewController setFrontViewController:navController1];
        [self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];

so I am setting appdelegate navcontroller to equal frontNavigationController then I use this to push a view on top of this... plus I got one place where I change the nav specs.

Thanks for all your help and time... if you can see any gotchas or better ways of doing the above, then please let me know - otherwise you can close the issue.

Thanks again.

iDevelopper commented 8 years ago

Have you the same titleView for all yours controllers?

amz4u2nv commented 8 years ago

Yup its the same -

    UIImage *img = [UIImage imageNamed:@"LogoBlack.png"];
    UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 25,  viewController.navigationController.navigationBar.frame.size.width, viewController.navigationController.navigationBar.frame.size.height-10)];

    [imgView setImage:img];
    // setContent mode aspect fit
    [imgView setContentMode:UIViewContentModeScaleAspectFit];
    [viewController.navigationController.view addSubview:imgView];

But I dont use titleview attribute, I add a subview, as the x, y cords were needed coz it wasn't centering correctly and overlapping when height was not set.

iDevelopper commented 8 years ago

Not centering in the rearView (the menu) ?

amz4u2nv commented 8 years ago

nope, the front view centering the logo - the logo will appear on all controllers.

iDevelopper commented 8 years ago

In my front view the logo is centered!

amz4u2nv commented 8 years ago

ahh yes i missed that... copied across to mine. Thanks

iDevelopper commented 8 years ago

For the title I added UINavigationControllerDelegate in AppDelegate. I think it is more simple than subclass UINavigationController. Just set the delegate in the first front view controller (ViewController1) and when you push a new front view controller from SW (In MenuTableViewController).

SWWebView 2.zip

What about this?

amz4u2nv commented 8 years ago

Thanks, will try it out.