Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Forever loop in unfoldLeftView #8

Open
flypigz opened this issue Dec 4, 2012 · 5 comments
Open

Forever loop in unfoldLeftView #8

flypigz opened this issue Dec 4, 2012 · 5 comments

Comments

@flypigz
Copy link

flypigz commented Dec 4, 2012

Actually this is an issue of PaperFold, but I can reproduce it easily with this PaperFoldMenuController demo.

Issue reproduce percentage: 100%

Issue reproduce steps using the demo project:

  1. add one left navigation bar button ("Show Menu") for the center view controller

1.1 update two methods below in PaperFoldMenuController.m

  • (void)setViewControllers:(NSMutableArray *)viewControllers
    {
    self.selectedIndex = NSNotFound; // Forces any child view controller to be removed.
    _viewControllers = viewControllers;
    if ([_viewControllers count]>0) [self setSelectedIndex:0];
    [self reloadMenu];

    // add top left button
    for (UIViewController *controller in _viewControllers) {
    [self addLeftButtonForViewController:controller];
    }
    }

  • (void)addViewController:(UIViewController*)viewController;
    {
    if (!_viewControllers) _viewControllers = [NSMutableArray array];
    [self.viewControllers addObject:viewController];
    [self reloadMenu];

    // add top left button
    [self addLeftButtonForViewController:viewController];
    }

1.2 add below methods in PaperFoldMenuController.m

pragma mark

pragma mark - Bar Button Action

///////////////////////////////////////////////////////////////////////////////////////////////////

  • (void)addLeftButtonForViewController:(UIViewController *)controller {
    UIViewController *rootViewController = controller;
    if ([rootViewController isKindOfClass:[UINavigationController class]]) {
    UINavigationController *nav = (UINavigationController *)rootViewController;
    //nav.navigationBar.tintColor = [UIColor colorWithHex:0xf1a0f8];
    if ([nav.viewControllers count] > 0) {
    rootViewController = [nav.viewControllers objectAtIndex:0];
    }
    }
    if (!rootViewController.navigationItem.leftBarButtonItem) {
    rootViewController.navigationItem.leftBarButtonItem = [self leftButtonForCenterPanel];
    }
    }
  • (UIBarButtonItem *)leftButtonForCenterPanel {
    return [[UIBarButtonItem alloc] initWithTitle:@"Show Menu" style:UIBarButtonItemStyleBordered target:self action:@selector(toggleLeftFoldPanel:)];
    }
  • (void)toggleLeftFoldPanel:(id)sender {
    NSLog(@"%s", PRETTY_FUNCTION);
    [self showMenu:YES animated:YES];
    }

after this, you can use the "Show menu" button to show the left menu, but you can't use it to hide the left menu with above code.

  1. in IOS6, we will use pull down gesture to display (pull down from the status bar) the system notification center, right? but if user does not execute this gesture correctly, it will leak to an issue:

2.1 put one finger in the Navigation bar of center view controller
2.2 pull down you finger but DO NOT exceed the bounds of the navigation bar (i.e. limit you pull down gesture in the navigation bar)
2.3 press the "Show Menu" bar button, which will invoke "[self showMenu:YES animated:YES];" method, but it won't work any more, and it will loop in the PaperFoldView::unfoldLeftView method forever....

I guess this happens because you capture the pull down gesture in somewhere, maybe this happens after you merged the code of PaperFold top and bottom fold feature (not sure if this feature has been merged to the main branch of PaperFold), and it break the codes.

Please msg me if you have any question about the issue reproduction.

Thanks in advanced.

@flypigz
Copy link
Author

flypigz commented Dec 5, 2012

The root cause should be

  1. when pan horizontally inside the navigation bar, the self.paperFoldInitialPanDirection will be set as PaperFoldInitialPanDirectionVertical
  2. when press the "Show Menu" Bar Button, the callStack would be

1)PaperFoldMenuController: showMenu:animated
2) PaperFoldView:: setPaperFoldState:PaperFoldStateLeftUnfolded animated:animated (animated is YES)
3) PaperFoldView:: setPaperFoldState:PaperFoldStateLeftUnfolded
4) PaperFoldView:: unfoldLeftView
5) PaperFoldView:: animateWithContentOffset:panned (the panned will be set as NO)

because the self.paperFoldInitialPanDirection is set as PaperFoldInitialPanDirectionVertical
so we are going into the wrong code path, actually it should run into the code path of
"if (self.paperFoldInitialPanDirection==PaperFoldInitialPanDirectionHorizontal)"

Fix: ??

set the self.paperFoldInitialPanDirection as PaperFoldInitialPanDirectionHorizontal before invoking animateWithContentOffset:panned method.

// unfold the left view

  • (void)unfoldLeftView:(NSTimer*)timer
    {
    [self.topFoldView setHidden:YES];
    [self.bottomFoldView setHidden:YES];
    [self.leftFoldView setHidden:NO];
    [self.rightFoldView setHidden:NO];

    CGAffineTransform transform = [self.contentView transform];
    float x = transform.tx + (self.leftFoldView.frame.size.width-transform.tx)/4;
    transform = CGAffineTransformMakeTranslation(x, 0);

    //DLog(@"before: %s, offset:%f, frame:%@, transform:%@", PRETTY_FUNCTION, x, NSStringFromCGRect(self.contentView.frame), NSStringFromCGAffineTransform(transform));

    [self.contentView setTransform:transform];

    //DLog(@"after : %s, offset:%f, frame:%@, transform:%@", PRETTY_FUNCTION, x, NSStringFromCGRect(self.contentView.frame), NSStringFromCGAffineTransform(transform));

    if (x>=self.leftFoldView.frame.size.width-2)
    {
    [timer invalidate];
    transform = CGAffineTransformMakeTranslation(self.leftFoldView.frame.size.width, 0);
    [self.contentView setTransform:transform];

    //        if (self.lastState!=PaperFoldStateLeftUnfolded && [self.delegate respondsToSelector:@selector(paperFoldView:didFoldAutomatically:toState:)])
    //        {
    //            [self.delegate paperFoldView:self didFoldAutomatically:self.isAutomatedFolding toState:PaperFoldStateLeftUnfolded];
    //        }
    //        [self setIsAutomatedFolding:NO];
    

    }

    //NSLog(@"####fixed self.PaperFoldInitialPanDirectionHorizontal:%d", self.paperFoldInitialPanDirection);
    // sometimes, the paperFoldInitialPanDirection would be PaperFoldInitialPanDirectionVertical,
    // this will lead to a forever loop, fix this right before animateWithContentOffset:panned method
    self.paperFoldInitialPanDirection = PaperFoldInitialPanDirectionHorizontal;

    // use the x value to animate folding
    [self animateWithContentOffset:CGPointMake(self.contentView.frame.origin.x, 0) panned:NO];
    }

Further Investigation

I am not sure if there would be some smilar issues for unfoldTopView or button view or right view, but you can use the similar solution to fix it. This only happens when invoking the PaperFoldView:: setPaperFoldState: method, because we directly re-used the last self.paperFoldInitialPanDirection value which is set in the onContentViewPanned method, and this value is obsolete.

For the pan to show top/bottom/left/right view, there is no such issue, because the self.paperFoldInitialPanDirection is updated each time.

@honcheng
Copy link
Owner

honcheng commented Dec 6, 2012

Wow. Thanks. Let me read this... and get back to you,

@honcheng
Copy link
Owner

honcheng commented Dec 6, 2012

Do u have a sample project u can send me?

@flypigz
Copy link
Author

flypigz commented Dec 6, 2012

I created a resp, try https://github.com/flypigz/PaperFoldMenuController-Forever-Loop, test step

  1. pan vertically inside the navigation bar
  2. click "Menu" button on top left
  3. check debug log, there should show the loop message

@marcobrambilla
Copy link

FYI I ran into the exact same problem... the fix proposed by @flypigz solved the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants