mwaterfall / MWPhotoBrowser

A simple iOS photo and video browser with grid view, captions and selections.
MIT License
8.75k stars 2.71k forks source link

Custom CaptionView with Autolayout causes stutter/jerks while scrolling slowly #453

Open jquiambao opened 8 years ago

jquiambao commented 8 years ago

I subclassed MWCaptionView that has 4 buttons and used AutoLayout to handle orientation change.

I initialize by code via [[NSBundle mainBundle] loadNibNamed:] and return it from captionViewForPhotoAtIndex:. When swiping through the image slowly, the view would jerk. Swiping it quickly would work fine.

Initially, I thought it was the loadNib was too slow, but then I cached my object (and tried UNib) and it didn't make a difference. I unchecked autolayout from my xib file and it worked smoothly.

markkrenek commented 8 years ago

I have the same stuttering even without subclassing MWCaptionView. If I don't provide any captions, there is no stuttering.

markkrenek commented 8 years ago

For me, removing the call to layoutVisiblePages in viewWillLayoutSubviews resolved my issue. I can't explain exactly why, but here's what I'm seeing: During a scroll, layout happens once via a call to tilePages, but then viewWillLayoutSubviews also gets called which triggers another layout pass. Between these two, something causes the contentOffset of the scrolling view to get reset to a page boundary, which you don't want when in the middle of a scroll (hence the stutter).

While it seems to make sense to layout the view when viewWillLayoutSubviews is called, I can't find any negative consequence from skipping it. Rotation still works.

markkrenek commented 8 years ago

Another solution that seems to work is to NOT change the contentOffset at the end of layoutVisiblePages if the user is scrolling the view.

Change:

_pagingScrollView.contentOffset = [self contentOffsetForPageAtIndex:indexPriorToLayout];

to:

if (!_pagingScrollView.dragging && !_pagingScrollView.decelerating)
    _pagingScrollView.contentOffset = [self contentOffsetForPageAtIndex:indexPriorToLayout];

I'm not really sure which route is best. There may be some other interactions going on that I'm not aware.

xiongyoudou commented 8 years ago

cool,i just know that:viewWillLayoutSubviews called ,so that" _pagingScrollView.contentOffset = [self contentOffsetForPageAtIndex:indexPriorToLayout]; "change the offset,result in jerks.but i dont know why viewWillLayoutSubviews is called ,in MWPhoto demo,the method will not be called.so i choose the second route to solve my problem,thanks

xilin commented 7 years ago

@markkrenek It works. Thanks!

TianXianBob commented 5 years ago

@markkrenek thanks it works.