44

这很奇怪,我想知道是否有人有任何想法?

我正在尝试滚动 UIScrollView 以响应 iPad 上的按钮按下。

如果我做:

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

滚动视图按预期跳转到所需位置,但我希望它滚动。但是,当我这样做时:

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

然后它什么也做不了!我有另一个滚动视图,它工作正常并按预期响应setContentOffset:YES,所以我很困惑。任何关于为什么滚动可能不会发生的想法都非常受欢迎!

此外,在使用- (void)scrollViewDidScroll:(UIScrollView *)sender 时根本没有收到任何东西,animated:YES但在使用时被调用animated:NO

4

9 回答 9

83

我也发生了这种情况,最终做了这个解决方法:

[UIView animateWithDuration:.25 animations:^{
    self.scrollView.contentOffset = ...;
}];
于 2012-03-09T16:45:31.967 回答
8

从个人经验来看,这个问题发生在 setContentOffset: 在动画有机会运行之前被多次调用时。

我还没有完全找到这个问题,但我相信问题是这样的:

setContentOffset:animated 被调用来设置新的偏移值。setContentOffset:随后使用相同的参数调用,从而取消动画。它还注意到新参数与旧参数相同,因此假设无需执行任何操作,即使动画尚未运行。

上面的解决方案以某种方式打破了这个循环,但也许一个不那么笨拙的解决方案是在代码中放置断点并消除多次调用。

于 2013-06-03T13:42:23.707 回答
2

很难用你给出的那段代码说。事实上,如果你说你有一个项目,一切都在相同的条件下工作,那么显然条件不一样:)我无法重现这个问题,但这里有一些假设2个案例:

  1. 使用 nib 创建 UIScrollView。

    • 只是不要忘记创建 IBOutlet 并将其绑定到 nib 中的 scrollView 元素。在一个简单的基于视图的应用程序中,我让 scrollView 像你希望的那样在动画中工作:YES 和 NO。但是为了工作

    -(void)scrollViewDidScroll:(UIScrollView *)sender;您必须设置委托:

yourScrollView.delegate = self;

其中'self'是类,你有你的scrollViewDidScroll函数;顺便说一句,此类必须符合“UIScrollViewDelegate”协议。

2.手动创建 UIScrollView 对象。

  • 这里的思路基本相同,所以我只提供一些简单的代码:

    -(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];
    }
    

这对我有用。希望这会有所帮助。

于 2011-06-15T21:55:33.963 回答
1

Xamarin.iOS 解决方案

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

这也可以使用解决UIView.Animate

UIView.Animate(
    duration: .25,
    animation: () =>
    {
       scrollView.SetContentOffset(new PointF((value * UIScreen.MainScreen.Bounds.Width), 0), true);
    }
);
于 2015-04-02T02:08:53.073 回答
1

我正在使用 tableviews,正如aepryus 解决方案所说:setContentOffset: is getting concurrently call with other animations

就我而言,我只是反转了这个命令:

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

像这样

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

动画在内容偏移成功更改后开始。

于 2018-07-14T14:20:05.677 回答
0

我遇到了同样的问题,即 ScrollView 不滚动。

然后我在视图上禁用了“使用自动布局”,之后 ScrollView 工作。

于 2014-05-26T03:58:50.070 回答
0

我有同样的问题,就我而言,我也在拦截:

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

之后立即调用此方法:(它不会等到动画结束):

[scrollView setContentOffset:currentOff animated: YES];

这意味着如果您有任何“等待”动画结束的逻辑并且您拦截 scrollViewDidEndScrollingAnimation 那么结果将是未定义的,即:过早结束动画。

编辑:接受的解决方案/解决方法:

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

在我的场景中也“有效”,因为直接设置 contentOffset 不会调用 scrollViewDidEndScrollingAnimation

于 2014-08-06T18:27:21.807 回答
0
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)

            })
    })

}
于 2016-05-30T07:39:21.807 回答
-2

你可以试试:

[scrollView setContentOffset:CGPointMake(240, 0) animated:YES];
于 2011-03-08T12:37:28.730 回答