Pageboy icon indicating copy to clipboard operation
Pageboy copied to clipboard

Screen got blank when trying to swipe fast

Open aaasifrz9 opened this issue 7 years ago • 21 comments

Hi,

I have added 5-6 child controllers. Now when I am swiping from start to end controller. Sometimes child view controller got blank while content on parent controller is properly showing. Then now when swiping back/forward, it shows child controller contents and again blanks. Tried sometimes back/forward then it loads child controller. It is not giving me any log in console. So I am not able to understand what is happening here.

Please help. Thanks in advance.

aaasifrz9 avatar Feb 20 '18 09:02 aaasifrz9

@aaasifrz9 hi, do you have a video or something that shows this? I'm find it hard to reproduce. Your PageboyViewControllerDataSource set up may also be useful 👍

msaps avatar Feb 23 '18 14:02 msaps

Hi @msaps ,

I have printed PageboyViewControllerDataSource and PageboyViewControllerDelegate logs in below link. Please check. Link: https://www.dropbox.com/s/2qxyx4vli71fg0p/Archive.zip?dl=0

aaasifrz9 avatar Feb 25 '18 12:02 aaasifrz9

Hi @msaps ,

Please take a look also. I have added 6 childs VC and when I tried to scroll it fast then the log is in the attached file. I don't understand didScrollToPosition jump to index 5 then 1 then 4 and again come back to 1 point something. Take a look lines from 6-11. And blank screen comes on line 8-10. Please help how to handle. It's too much critical for me. Thanks in advance.

Log.rtf.zip

aaasifrz9 avatar Feb 27 '18 02:02 aaasifrz9

Hi @msaps ,

My PageBoyViewController code is like

var pageControllers: [ChildViewController]!

After that in viewDidLoad, I fetch data from server than created

let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)

var viewControllers = [ChildViewController]()
for i in 0 ..< numberOfPages {
    let viewController = storyboard.instantiateViewController(withIdentifier: "ChildViewController") as! ChildViewController
    viewController.index = i
    if i == 0 {
        self.currentChildViewController = viewController
    }
    viewController.delegate = self
    viewControllers.append(viewController)
}
self.pageControllers = viewControllers

Then I set

dataSource = self
delegate = self
extension PageViewController: PageboyViewControllerDataSource {
    
    func numberOfViewControllers(in pageboyViewController: PageboyViewController) -> Int {
        return self.pageControllers.count
    }
    
    func viewController(for pageboyViewController: PageboyViewController,
                        at index: PageboyViewController.PageIndex) -> UIViewController? {
        return self.pageControllers[index]
    }
    
    func defaultPage(for pageboyViewController: PageboyViewController) -> PageboyViewController.Page? {
        return nil
    }
}

// MARK: PageboyViewControllerDelegate
extension PageViewController: PageboyViewControllerDelegate {
    
    func pageboyViewController(_ pageboyViewController: PageboyViewController,
                               willScrollToPageAt index: Int,
                               direction: PageboyViewController.NavigationDirection,
                               animated: Bool) {
                        print("willScrollToPageAtIndex: \(index)")
    }
    
    func pageboyViewController(_ pageboyViewController: PageboyViewController,
                               didScrollTo position: CGPoint,
                               direction: PageboyViewController.NavigationDirection,
                               animated: Bool) {
                        print("didScrollToPosition: \(position)")
    }
    
    func pageboyViewController(_ pageboyViewController: PageboyViewController,
                               didScrollToPageAt index: Int,
                               direction: PageboyViewController.NavigationDirection,
                               animated: Bool) {
                        print("didScrollToPageAtIndex: \(index)")
    }
    
    func pageboyViewController(_ pageboyViewController: PageboyViewController,
                               didReloadWith currentViewController: UIViewController,
                               currentPageIndex: PageboyViewController.PageIndex) {
        print("didReloadWith)")
    }
}

I am not able to recognise why it jumps as described in above comment and show blank screen. Please help, thanks in advance.

aaasifrz9 avatar Feb 27 '18 18:02 aaasifrz9

@aaasifrz9 hmm your code all looks good. I'll investigate and see what I can find, maybe something strange in the page detection logic. Weird it hasn't come up before though!

msaps avatar Mar 04 '18 11:03 msaps

Hi @msaps ,

I analyzed that when we try to scroll fast then x position jumps from current page to last/next to next page directly.

Can we load next/previous page when current page loads as like UIPagerViewController using PageBoy framework? If possible, please suggest how can we implement?

Regards, Asif

aaasifrz9 avatar Mar 09 '18 05:03 aaasifrz9

I got a whole white view sometimes.

DamonChen117 avatar Mar 11 '18 04:03 DamonChen117

Yes, white because parent view controller's background color is white. In my case I am getting whole black due to black background color.

aaasifrz9 avatar Mar 11 '18 04:03 aaasifrz9

@DamonChen117 @aaasifrz9 how hard is this to reproduce? It is probably a UIPageViewController issue, could be related to the discussion in #113?

Any concrete reproduction steps, demo projects or videos would be much appreciated.

msaps avatar Mar 11 '18 11:03 msaps

Hi @msaps ,

As per comment in #151 , the viewController(for: at:) data source function is called whenever the internal UIPageViewController asks for a view controller in pageViewController(viewControllerBefore:) or pageViewController(viewControllerAfter:) but when I swipe it only load current view controller. And UIPageViewController loads current and next/previous as per swipe direction also.

My question is:-

Can we load next/previous page also when current page loads as like UIPageViewController using PageBoy framework?

Actually I think if we can load next/previous view controller also then may be can it resolves jump problem here.

If possible, please suggest how can we implement?

Thanks for above response.

aaasifrz9 avatar Mar 14 '18 06:03 aaasifrz9

@aaasifrz9 what I was meaning by that comment is that the data source in PageboyViewController behaves exactly like UIPageViewController as that is what it is using underneath. So the 'next' view controller is loaded at the exact same time as it would be using a raw UIPageViewController.

msaps avatar Mar 14 '18 09:03 msaps

Same. Sometimes its totally goes black.

gaborcsontos avatar Mar 18 '18 13:03 gaborcsontos

Hi @msaps ,

I can understand that Pageboy is using UIPageViewControllerDataSource internally but it is not loading next/prev view controller as UIPageViewController loading. Has jump/black screen issue solved? Please help.

aaasifrz9 avatar Mar 27 '18 01:03 aaasifrz9

@aaasifrz9 as you can see and I have specified, PageboyViewController will ask for the next/previous view controller in the exact same way as UIPageViewController. It is just masked by a different data source:

screen shot 2018-03-27 at 10 03 46

The issue itself I am still investigating.

msaps avatar Mar 27 '18 08:03 msaps

@aaasifrz9 @DamonChen117 @gaborcsontos think this is related to #157 - and I also believe I might have found a fix 🎉

msaps avatar Apr 05 '18 19:04 msaps

@aaasifrz9 @DamonChen117 @gaborcsontos can you check out 2.5.0 and see how you get on...

(If you're using Tabman, I'll release a new version tomorrow that uses Pageboy 2.5)

msaps avatar Apr 05 '18 20:04 msaps

I am still having this issue... takes a while of scrolling really fast and like crazy, this never happened to me in normal conditions... got this in 2.6.1 and 3.0 too

Vapor-ios avatar Oct 13 '18 12:10 Vapor-ios

I have this issue especially when swiping very fast (even using 3-4 fingers) and getting these error messages: <_UISystemGestureGateGestureRecognizer: 0x2800c40f0>: Gesture: Failed to receive system gesture state notification before next touch

I know this is a corner case but I thought you'd like to know and maybe fix it somewhere in the future.

Vapor-ios avatar Oct 14 '18 11:10 Vapor-ios

@msaps I was able to cause this to happen.

Basic structure:

-Parent page controller, child pages. Child page custom delegate type = parent

-child pages communicate back to parent page controller via delegate pattern

-Button press on child view controller (page 1) calls out to delegate "go to 2nd page"

-Parent method looks like this:

/// Child delegate callback
func goToSecond() {
   setViewControllers([second],
                          direction: .forward,
                          animated: true,
                          completion: nil)
}

Here's the kicker: The button on the child controller called the "delegate?.goToSecond()" on touch down from a UIButton, so what could happen is the user could hypothetically tap twice VERY QUICKLY, call the delegate twice, thus calling the above function twice very rapidly, and boom you now have a black screen. It's possible this is the same issue with "swiping too fast". Idk if it's relevant but for this page controller there were also only two pages total. So 1st page, then extremely rapid duplicate calls to the above function (which is also the last page in the collection) can cause this.

RamblinWreck77 avatar Jan 07 '19 17:01 RamblinWreck77

I have this problem. Does it have a workaround? ezgif-1-5d9192d2b678

dfmarulanda avatar May 28 '19 22:05 dfmarulanda

@dfmarulanda Do you call super class methods also?

sugitatestblue avatar Jun 28 '22 12:06 sugitatestblue