scrollViewWillEndDragging:withVelocity:targetContentOffset: not working on the edges of a UISCrollView

倾然丶 夕夏残阳落幕 提交于 2020-01-20 20:06:29

问题


I'm trying to implement a custom tab bar which is scrollable and has paging at each tab bar item. For that i'm using the delegate scrollViewWillEndDragging:withVelocity:targetContentOffset: which works perfectly with one problem.

The way my paging works is, if the contentOffset is near the right item, it the targetContentOffset changes to the offset of that item. Same thing for the left side.

The problem is, whenever I'm at at the left half of the first item and the right of the last (the scroll view works horizontally) it's supposed to go to ContentOffset 0 and the content offset of the rightmost item (minus the ones on screen), but it doesn't.

I checked with the debugger and the targetContentOffset->x is indeed 0 (in the first case - left of the leftmost item). So the problem is the UIScrollView not scrolling there. I'm lost.

Here is my implemented delegate:

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView
                 withVelocity:(CGPoint)velocity
          targetContentOffset:(inout CGPoint *)targetContentOffset{
     NSInteger index = lrintf(targetContentOffset->x/self.tabWidth);
     targetContentOffset->x = index * self.tabWidth;
}

Here is the diagram explaining what i want to do.

|-------|-------|-------|-------|-------|-------|-------|
|       |       |       |       |       |       |       |
|       |       |       |       |       |       |       |
|_______|_______|_______|_______|_______|_______|_______|

        |_______________________________________|
         where it is and i scroll it to the left

   <----|

   |_______________________________________|
              where it would stop

|_______________________________________|
        where i want it to stop

回答1:


This is a known issue it seems. After some investigation and talking to other people it was suggested it could be a bug, which turned out to be correct. I reported it to Apple and was it marked as duplicate but is still open. Just answering for those of you with the same problem. I workaround it like Big Papoo suggests, by using an offset close to what I want (0.1 seems to do it). The same for the right end.




回答2:


Issue Fixed on iOS 6.0.

Now it works as it should.




回答3:


I tried setting the final offset to something slightly off zero or the content size as suggested by Big Papoo but noticed that this removes the over-scroll bounce. My solution to this was to check the original targetContentOffset to see if it is equal to zero or the contentSize and leaving it if it is:

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {

    float expectedOffset = targetContentOffset->x;
    if (expectedOffset == 0 || expectedOffset == scrollView.contentSize.width) return; // Scroll view will bounce so leave the targetContentOffset.

    float targetOffset = [self roundedOffset:expectedOffset]; // Round your offset.

    // Adjust the offset to make sure it works.
    if (targetOffset == 0) targetOffset = 1;
    else if (targetOffset == SCROLLVIEW_WIDTH) targetOffset = SCROLLVIEW_WIDTH - 1;

    targetContentOffset->x = targetOffset;
}

You can of course then use scrollViewDidEndDecelerating: to to move the scrollview that 1 point.




回答4:


I found 2 undocumented behaviors that you may investigate : - Setting zero as the final offset doesn't work, I suggest putting 1 or anything greater than zero (0.5 may work, not tested) - You'd better check the velocity sign and compute your final offset to be on the left or right side of the current point where the user removed is finger. Don't try to make the scrolling go backward on the other side.




回答5:


If you're using a horizontal table view, then inside your scrollViewWillEndDragging:withVelocity:targetContentOffset: function, you can call:

[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:<index> inSection:<section>] atScrollPosition:UITableViewScrollPositionTop animated:YES];

I found this to work much better than trying to manipulate targetContentOffset->y in a horizontal table view.



来源:https://stackoverflow.com/questions/10880434/scrollviewwillenddraggingwithvelocitytargetcontentoffset-not-working-on-the-e

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!