33

I've got a UIPageViewController set up paging my ImageViewController.

The ImageViewController contains a UIScrollView with a UIImageView inside. Nothing else.

I'm testing at the moment with 3 "items" in my datasource for the UIPageViewController (i.e. three pages).

It all works fine and I can scroll and zoom and then page for about 30 seconds and then suddenly I get this warning...

*** Assertion failure in -[_UIQueuingScrollView _didScrollWithAnimation:force:], /SourceCache/UIKit/UIKit-2372/_UIQueuingScrollView.m:778

I've got no idea where to start debugging it though as it doesn't point to any of my code and there isn't any of my code in the stack or anything.

Can someone give me a pointer as to where to start debugging this.

EDIT

I've done a bit more testing. It seems to happen if the scrollView is decelerating (i.e. after a flick) and then I try to transition the PageViewController to another ViewController as the scrollview is still moving.

The app crashes about 20% of the way through the transition to the next page.

EDIT 2

The error seems to stop on the line _cache_getImp (not sure if that's a capital i or lowercase L).

EDIT 3

This gets better. I just downloaded Apple's PhotoScroller sample app to see if they got round the problem a different way. Well, no, they didn't. The sample app crashes in exactly the same way mine does! You have to zoom and scroll and transition pages at the same time to make it more likely to crash but it happens on it's own too it just might take longer to happen.

Mehul Mistri
  • 15,037
  • 14
  • 70
  • 94
Fogmeister
  • 76,236
  • 42
  • 207
  • 306
  • I don't know the answer but the problem sounds like some I've seen where some delegate method is being invoked after the delegate object has gone away. Is there a delegate involved in your scrolling? – Phillip Mills Oct 16 '12 at 14:49
  • The only delegate method I'm using is viewForZoomingInScrollView. Is there a way to remove the delegate or deal with the fact it isn't there any more? – Fogmeister Oct 16 '12 at 14:50
  • 1
    The bit in your question that made me think of this was "transition the PageViewController to another ViewController". When that is about to happen do you have an opportunity to set the scroll view delegate to nil? (Keeping in mind this is a wild guess at what the problem might be. :) ) – Phillip Mills Oct 16 '12 at 14:58
  • 1
    Ah, I thought you had it there. There is a "willTransition..." method and I'm clearing the delegate on the ViewControllers scrollViews when I get into there but it didn't change it. – Fogmeister Oct 16 '12 at 15:05
  • 2
    I'm also having this problem. Did you get around it? Another related problem I'm having is that the scrollview displaying the imageview starts intercepting touches which means the page view controller won't recognize swipe gestures. Any ideas? – Remover Dec 03 '12 at 12:42
  • @Remover no, I didn't get round the problem. In the end I just removed the UIScrollView and scaled (aspect fit) the images to the screen. Not ideal but it works and doesn't crash. I also raised a bug report with Apple but I haven't heard anything yet. – Fogmeister Jan 15 '13 at 17:40
  • @Fogmeister please accept the answer , if you get it right. – SwapnilPopat Mar 08 '14 at 05:29
  • @PeacefulWarrior when an answer is correct I'll accept it. Up til now no answer has managed to fix this. – Fogmeister Mar 08 '14 at 09:40

5 Answers5

5

Came up with a solution! In my case I have a UIPageViewController with UIPageViewControllerTransitionStyleScroll as well as next buttons that allow the user to advance through my viewpager by tapping. I am getting this crash when the user presses a next button and drags around slightly before releasing their finger (still within the frame of the button). It appears that the dragging within the button is interfering with UIPageViewController's pan gesture recognizer in this case, and that's what causes the crash.

While it's pretty unlikely that the user will get in this state, I've come up with a relatively simple solution the prevents my app from crashing if it does happen. I have a boolean that represents if the user is in a valid state to move to the next screen and set it to YES on touch down, then to NO if the user drags anywhere inside my button. Then, on touchUp (nextPressed) I check the boolean before moving my UIPageViewController programatically.

- (IBAction)touchDown:(id)sender
{
  self.shouldAdvanceToNextScreen = YES;
}

- (IBAction)touchDragInside:(id)sender
{
  self.shouldAdvanceToNextScreen = NO;
}

- (IBAction)nextPressed:(id)sender
{
  if (self.shouldAdvanceToNextScreen) {
    UIViewController *initialViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"TutorialScreen2"];
    NSArray *viewControllers = [NSArray arrayWithObject:initialViewController];
    [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
  }
}

The downside is that nothing will happen even though the user still released their finger within the button frame. However, I prefer this over a crash and see this as a pretty rare edge case regardless. I'd expect the user would just tap again - this time without a tap & drag - and move forward successfully.

I'd welcome any ideas on taking this a step further and preventing the clash between the touch drag and the UIPageViewController altogether.

Kyle Clegg
  • 38,547
  • 26
  • 130
  • 141
  • Thanks for this, I wasted a day trying to fix this crash... I simplified this to two methods: `touchDragInside:` that sets `buttonDragged = true`, and `buttonPressed:` that only performs the action if `!buttonDragged` and then resets `buttonDragged` back to `false`. – Kuba Suder Jun 02 '15 at 14:09
  • @KubaSuder what if the user performs a touchDragInside then releases their finger outside the button's touch target, and then normal taps the button? – Kyle Clegg Jun 03 '15 at 02:05
  • Hmm, you're right, I haven't tested that. Although not a big problem, because they will just have to press the button second time... But it will be better to fix this. – Kuba Suder Jun 03 '15 at 12:59
1

Have you tried disabling bouncing in the UIScrollView? That worked for me and solved my other problem too alluded to in my comment above.

Remover
  • 1,616
  • 1
  • 17
  • 27
1

I have been fighting with this all day. My Conclusions:

If you have a scrollview as the showing ViewController and you are delegate of the scrolls: you're in trouble. Even with the PageViewController configured with Horizontal scrolling, a vertical scrolling on your view will trigger an event. -> this does not cause trouble if: you scroll back to the top of your view before (Not sure how to fix this).

There are good StackOverflow threads like this one.

Basically the solution is:

1 [yourView setViewControllers:yourControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];

2 Use UIPageViewControllerTransitionStylePageCurl as the transition Style.

This fixed most of my problems.

If someone has a solution for the delegation problems with the scrolling, will be most wellcome

Community
  • 1
  • 1
wolffan
  • 1,084
  • 10
  • 15
0

I had a similar problem. My setup was a UIPageViewController and I was loading view controllers with an UIImageView inside. When interacting while the UIPageViewController was scrolling I got the same crash log.

I fixed it by creating a UILongPressGestureRecognizer and add to the UIPageViewController's scroll view.

  1. Created my own subclass of UIPageViewController (Solution is specific for my case but can easily used as a generic solution)

  2. Find the inner UIScrollView of the UIPageViewController

    - (UIScrollView *)findScrollView
    {
        UIScrollView *scrollView;
        for (id subview in self.view.subviews)
        {
            if ([subview isKindOfClass:UIScrollView.class])
            {
                scrollView = subview;
                break;
            }
        }
    
        return scrollView;
    }
    
  3. Add the long tap gesture recognizer to the inner scroll view and point its action to a method or nil

    /**
     *  On tap-hold the page view controller crashes as soon as it pages to a new view controller.
     *  Setting a long press gesture to ignore the hold.
     */
    - (void)listenForLongPressGestureOnScrollView:(UIScrollView *)scrollView
    {
        UILongPressGestureRecognizer *longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:nil];
        [longPressGestureRecognizer setMinimumPressDuration:0.5];
        [scrollView addGestureRecognizer:longPressGestureRecognizer];
    }
    
Martin Stolz
  • 5,176
  • 3
  • 21
  • 19
  • Sounds good. I'll have a play around. Still though, all this hacking makes me think that it's broken somewhere :D – Fogmeister May 13 '14 at 17:02
-1

It surely looks like a bug in iOS 8 and 9. (and the "answers" down below attempt to work around that)

Feel free to file a ticket on bugreport.apple.com Do be sure to specify how to crash PhotoScroller

Include all iOS versions you've seen it crash on

To date I've seen:

Assertion failure in -[XXX.TrackingPageViewController queuingScrollView:didEndManualScroll:toRevealView:direction:animated:didFinish:didComplete:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3512.60.12/UIPageViewController.m:2028

Assertion failure in -[_UIQueuingScrollView _didScrollWithAnimation:force:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3512.60.12/_UIQueuingScrollView.m:785 (lldb)

I'll keep the list updated (Despite the downvoting, however massive). Stay tuned.

It does not look like our bug.

UPD 2016 09 27 (on Xcode 8 now):

Assertion failure in -[XXX.TrackingPageViewController queuingScrollView:didEndManualScroll:toRevealView:direction:animated:didFinish:didComplete:], /SourceCache/UIKit/UIKit-3347.44.2.2/UIPageViewController.m:1875

awesome

Anton Tropashko
  • 5,486
  • 5
  • 41
  • 66
  • This does not really answer the question. If you have a different question, you can ask it by clicking [Ask Question](http://stackoverflow.com/questions/ask). You can also [add a bounty](http://stackoverflow.com/help/privileges/set-bounties) to draw more attention to this question. - [From Review](/review/low-quality-posts/13662371) – egor.zhdan Sep 14 '16 at 13:08
  • "42" style answers are acceptable for nonworkaroundable questions. – Anton Tropashko Sep 14 '16 at 13:40
  • This post doesn't help the OP to solve their issue, so it is not an answer. – egor.zhdan Sep 14 '16 at 13:46
  • which part of my answer "looks like a bug in ios 8 and 9" you do not understand? – Anton Tropashko Sep 14 '16 at 19:51
  • Again: your post doesn't even mention any solution of the issue. It should have been written as a comment. Next time please take a look at http://stackoverflow.com/help/how-to-answer – egor.zhdan Sep 14 '16 at 20:39
  • 2018 and this problem is still happening... C'mon Apple. – Pedro Paulo Amorim Jun 06 '18 at 18:38
  • Pedro, this is not a bug in Xcode per se, this is a bug in UIKit – Anton Tropashko Oct 29 '19 at 12:51