John-Lluch / SWRevealViewController

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

Crash on unit test when adding gesture recognizer #209

Closed Broich closed 10 years ago

Broich commented 10 years ago

Today I came across the following issue. I wanted to run my unit tests after some changes to the program and suddenly the application crashes when I hit Product > Test. I subclass a UITabBarController and when assigning the self.revealViewController.panGesture to self.view I get a NSInvalidArgumentException claiming that the gesture is nil.

- (void)viewDidLoad
{
    [super viewDidLoad];

    BOOL topOfStack = self.navigationController.viewControllers.count > 1 ? NO : YES;

    if (topOfStack) {
        self.revealBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"SidebarIconReveal"] style:UIBarButtonItemStylePlain target:self.revealViewController action:@selector(revealToggle:)];
        self.navigationItem.leftBarButtonItem = self.revealBarButtonItem;
        [self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
    }

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

    self.navigationController.navigationBar.translucent = NO;
}

Crash occurs in the line [self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer]; and it only happens when testing. When I hit Product > Run the application runs like expected and I can use the pan gesture without a problem. Indeed the pan gesture is nil at that point but what is different when Test compared to Run?

John-Lluch commented 10 years ago

Hi, this most probably happens because your controller is not yet added to the controller hierarchy by the time you request its revealViewController, thus it is nil at such time. This has nothing to do with the class. Please look at your code and determine why this is the case. I certainly can not help much more on this. Thanks.

Broich commented 10 years ago

You are right. I found a way to solve this. If someone encounters this problem this might be an easy solution:

if (self.revealViewController.panGestureRecognizer) {
    [self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
}

Thanks for looking into this!

John-Lluch commented 10 years ago

Hi Broich, you can test if the revealViewController is not nil, as this is the root cause. Still, this should never happen on the viewDidLoad of a revealViewController's childController because at this point it should be already added to the controller hierarchy. The fact that this only fails on your unit testing (as you seem to imply) but not on the normal app execution makes me think that something is wrong on that particular scenario. Thanks

Broich commented 10 years ago

Yes, the strange thing is that self.revealViewController is not nil. It's only the addition of the gesture that crashes the application.

John-Lluch commented 10 years ago

So the revealViewController returns nil after calling panGestureRecognizer?. Then this is even more strange. I do not get how this can be, as the class just creates one and delivers it (!). Are you sure self.revealViewController does not return nil?

Broich commented 10 years ago

I'm sorry! Of course it is nil. I just checked it again. I try to set the panGesture in a subclass of UITabBarController and this subclass seems to be independent from reveal controller. I just don't get why this only happening while testing. There's a screenshot of my scenario.

screen shot 2014-03-17 at 7 03 39 pm

vincecima commented 10 years ago

Also seeing this using Kiwi for spec testing. Will use the workaround for now and will try to add more detailed info.