开发者

Problem with uiscrollview setcontentoffset animated not scrolling when animated:yes is set

This is very odd and I'm wondering if anyone has any thoughts?

I'm trying to scroll a UIScrollView in response to a button press on the iPad.

If I do:

CGPoint currentOff = scrollView.contentOffset;
currentOff.x+=240;
[scrollView setContentOffset:currentOff animated: NO];

The scroll view jumps to the required position as expected, but I want it to scroll. However, when I do:

CGPoint currentOff = scrollView.contentOffset;
currentOff.x+=240;
[scrollView setContentOffset:currentOff animated: YES];

Then it doesn't do anything! I have another scroll view which is working properly and responds to setContentOffset:YES as expected, so I am quite puzzled. Any ideas on why scrolling might not happen are most welcome!

Also, 开发者_开发问答- (void)scrollViewDidScroll:(UIScrollView *)sender is not receiving anything at all when animated:YES is used but is invoked when animated:NO is used!


I had this happen too and ended up doing this workaround:

[UIView animateWithDuration:.25 animations:^{
    self.scrollView.contentOffset = ...;
}];


Speaking from personal experience, this problem occurs when setContentOffset: is getting called multiple times before the animation has had a chance to run.

I haven't totally tracked down the issue, but I believe the problem goes something like this:

setContentOffset:animated gets called which sets the new offset value. setContentOffset: subsequently gets called with the same parameters, which cancels the animation. It also notices that the new parameters are the same as the old parameters so assumes nothing needs to be done, even though the animation hasn't run yet.

The solution above somehow breaks this cycle, but perhaps a less kludgy solution is to put break points in the code and eliminate the multiple calls.


Hard to say with that piece of code you gave. And in fact, if you're saying, that you have a project, where everything is working under the same conditions, then obviously the conditions aren't the same :) I couldn't reproduce the issue, but here are some assumptions for 2 cases:

  1. Creation of UIScrollView with nib.

    • Just don't forget to create IBOutlet and to bound it to the scrollView element in nib. In a simple view based application just after that I got scrollView working as you wished in animated: both YES and NO. But to make work

    -(void)scrollViewDidScroll:(UIScrollView *)sender; you must set the delegate:

yourScrollView.delegate = self;

where 'self' is class, where you have your scrollViewDidScroll function; btw this class must conform to the 'UIScrollViewDelegate' protocol.

2.Creation of UIScrollView object manually.

  • here the idea is basically the same, so I'll just provide some simple code:

    -(void) creatingScrollView {
        UIScrollView *newScroll = [[UIScrollView alloc] initWithFrame:CGRectMake(20, 5, 280, 44)];
        newScroll.pagingEnabled = YES;
        newScroll.showsVerticalScrollIndicator = NO;
        newScroll.showsHorizontalScrollIndicator = NO;
    
        // ... some subviews being added to our scroll view
    
        newScroll.delegate = self;
        [self.view addSubview:newScroll];
        [newScroll release];
    }
    

This works for me. Hope this is helpful.


I'm working with tableviews, as aepryus solution's says: setContentOffset: is getting called concurrently with other animations.

In my case I've just invert this commands:

[tableView reloadData];
[tableView setContentOffset:CGPointMake(240, 0) animated:FALSE];

like this

[tableView setContentOffset:CGPointMake(240, 0) animated:FALSE];
[tableView reloadData];

The animation start after the content offset has changed successfully.


Solution for Xamarin.iOS

InvokeOnMainThread(() =>
{
  scrollView.SetContentOffset(new PointF((page * UIScreen.MainScreen.Bounds.Width), 0), true);
});

This can also be solved using UIView.Animate

UIView.Animate(
    duration: .25,
    animation: () =>
    {
       scrollView.SetContentOffset(new PointF((value * UIScreen.MainScreen.Bounds.Width), 0), true);
    }
);


func scrollViewDidScroll(scrollView: UIScrollView) {

    dispatch_async(dispatch_get_main_queue(),{

        UIView.animateWithDuration(0.10, animations: { () -> Void in

            let loginScrollViewCurrentPosition:CGPoint = CGPointMake(self.loginScrollView.contentOffset.x, self.loginScrollView.contentOffset.y) as CGPoint
            self.loginScrollView.setContentOffset(loginScrollViewCurrentPosition, animated: true)

            })
    })

}


I faced the same problem wiehre the ScrollView doesn't scroll.

Then I disabled "Use Auto Layout" on the view, and after that the ScrollView works.


I had the same issue, in my case I was also intercepting:

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {...}

This method is called immediately after: (It doesn't wait until the end of the animation):

[scrollView setContentOffset:currentOff animated: YES];

Which means that if you have got any logic that "waits" the end of the animation and you intercept scrollViewDidEndScrollingAnimation then the result will be undefined, IE: ending the animation prematurely.

EDIT: The accepted solution/workaround:

[UIView animateWithDuration:.25 animations:^{
    self.scrollView.contentOffset = ...;
}];

Also "works" in my scenario because setting the contentOffset directly doesn't invoke scrollViewDidEndScrollingAnimation


You could try:

[scrollView setContentOffset:CGPointMake(240, 0) animated:YES];
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜