How do I use SWRevealViewController with unwind se

2019-02-15 07:43发布

问题:

I have a sequence of views that are pushed on top of each other on a Navigation Controller. I would like to do two things with these views:

  1. To open the Rear menu view from all of them;
  2. To be able to navigate back the stack using Unwind segues.

I found out that if I push view controllers on top of each other using regular push segues then the unwind segue works as expected, but then the self.revealViewController on each view controller is not set and the Menu can't be called using the revealToggle: selector.

If I change the push segues to subclasses of SWRevealViewControllerSeguePushController then the views are pushed on top of each other and the Menu can be called from any of them using the revealToggle. Unfortunately, the unwind segues stop working (I think this might be because the view controllers are stacked using addChild instead of pushViewController on the SWRevealViewController class).

Is there a way of working together with SWRevealViewController and Unwind Segues?

Below there is an example storyboard:

The first view controller is the navigation controller; the second is the SWRevealViewController; the three view controllers below navigate one to each other, and the third has an unwind segue to the first. The first and third controllers have buttons that open the menu.

As I stated before, if the segues between the bottom view controllers are regular push segues then the unwind segue works as expected; the menu button from the first view controller works (as it is connected directly to the SWRevealViewController), but the menu button from the third view controller doesn't.

Switching the segue types to SWRevealViewControllerSeguePushController makes the menu buttons from the first and third view controllers work correctly, but the unwind segue stops working.

Oh, and I tested using "popToRootViewControllerAnimated:" and it also doesn't work if the segues are set to SWRevealViewControllerSeguePushController.

回答1:

I posted this question on SWRevealViewControllers github site and received an answer from Patrick Bodet who was EXTREMELY helpful. I will post the answer below so it may help somebody in the same situation as I.

I had to update the storyboard and added an additional navigation controller as shown below.

As shown in the figure, I wanted to be able to push view controllers on top of each other and also to unwind the segues both to the Login screen (from the Menu) and from stacked view controllers.

On my previous attempts, it seemed as if SWRevealViewController wasn't able to cope with proper navigation segues. Patrick's first suggestion was to move the original navigation controller from before the RevealViewController to before the First view controller. That actually worked, by I still needed to be able to unwind segue from the Menu to the Login screen, so I needed an additional navigation controller.

As suggested by Patrick, I added an additional Navigation Controller. And embarrassingly at the end I realised the button that pointed from the third to the first view controller had both an ibaction and a segue to the first, so that was why it was acting all weird! :-(

So, for the storyboard shown above, in order to work you just use regular Push segues for the view controllers. No need to use SWRevealViewControllerSeguePushController segues.

The code for First and Third view controllers is like this:

#import "ThirdViewController.h"
#import "SWRevealViewController.h"
#import "FirstViewController.h"

@interface ThirdViewController ()
@property (weak, nonatomic) IBOutlet UIBarButtonItem *menuButton;
@end

@implementation ThirdViewController 
- (void)viewDidLoad {
    [super viewDidLoad];

    SWRevealViewController *revealViewController = self.revealViewController;

    if (revealViewController) {
        [self.menuButton setTarget: revealViewController];
        [self.menuButton setAction: @selector( revealToggle: )];
    }
}

- (IBAction)returnToFirst:(id)sender {
    [self performSegueWithIdentifier:@"First" sender:self];
    //[self.navigationController popToRootViewControllerAnimated:YES];
}  
@end