UIScrollView工作正常,但scrollRectToVisible:无效。

67

我以前使用过UIScrollView,现在也在使用,从未遇到问题。我正在将其添加到一个旧的应用程序中,虽然它按预期工作(我可以查看内容,用手指滚动,所有边界和尺寸都设置正确,因此内容中没有空白区域等),但我无法使scrollToRectVisible起作用。我甚至简化了调用,只将其移动到0,0位置:

 [scrollView scrollRectToVisible:CGRectMake(0, 0, 10, 10) animated:YES];

或将其移动到0,200:

 [scrollView scrollRectToVisible:CGRectMake(0, 200, 10, 10) animated:YES];
我甚至制作了一个快速应用程序来测试这个功能,我可以像我期望的那样使用scrollRectToVisible。但是在我的旧应用程序中,我似乎无法使它有任何作用。
我可以使用setContentOffset:使scrollView滚动,但那不是我想要的。
这个scrollView及其内容是通过IB在nib中定义并与IBOutlet一起使用的。我在我的应用程序中仅使用了以下代码来处理scrollView:
 [scrollView setContentSize:CGSizeMake(scrollView.contentSize.width, imageView.frame.size.height)];

我只对垂直滚动感兴趣,而不是水平滚动。

有人遇到过这样的问题吗?

我已经比较了两个应用程序中scrollView的属性,它们是相同的。

附加说明:

我的scrollViews框架是:0.000000 0.000000 480.000000 179.000000

我的scrollViews内容大小为:0.000000 324.000000

它仍然表现得好像我想要滚动到的矩形已经可见,不需要滚动。不确定是否是这种情况。 这真是太奇怪了。看起来像是一个很容易解决的问题...

第二个补充说明:

这是我如何没有使用scrollRectToVisible进行操作的:

CGPoint point = myRect.origin;
if (![clefScrollView pointInside:point withEvent:nil]) {
    point.x = 0;
    if (point.y > clefScrollView.contentSize.height - clefScrollView.bounds.size.height)
        point.y = clefScrollView.contentSize.height - clefScrollView.bounds.size.height;
    [clefScrollView setContentOffset:point animated: YES];
}

这个scrollView的其他方面都如预期一样工作,但是scrollRectToVisible方法却不行。为什么?有什么猜测吗?

8个回答

118

一个多月后,我终于找到了答案。虽然上面的替代方案很好用,但这个问题一直困扰着我,最终我还是解决了它。原来这只是一个有点蠢的错误。

下面是我在viewDidLoad中设置scrollView的旧代码:

[clefScrollView setContentSize:CGSizeMake(clefScrollView.contentSize.width, clefView.frame.size.height)];

ScrollView的高度或宽度值不能为0!我认为这是因为我假设ScrollView的大小始终具有有效尺寸而忽略了一个维度为零的事实。

以下代码可以正常工作:

[clefScrollView setContentSize:CGSizeMake(clefView.frame.size.width, clefView.frame.size.height)];

不错的侦探工作,mahboudz。顺便说一句,我怀疑问题并不是 ScrollView 不能具有大小为零的尺寸,而是它必须足够大以包含请求的矩形!干杯,Orion。 - orion elenzil
3
这并不完全正确 - 参见下面Orion的答案(我的宽度/高度不为零,而不是'0'导致了问题...) - Adam
你想将0设置为1。设置高度有时会让内容大小超出实际需要的范围(假设它不在顶部/底部栏下面),从而打击你的脸。 - desudesudesu
让我发疯了!非常感谢 ;) - sachadso
谢谢!我的问题出在自动布局-contentSize的宽度为0。如果你也遇到了这个问题,那是因为你没有把所有内容放在滚动视图内的contentView中:http://spin.atomicobject.com/2014/03/05/uiscrollview-autolayout-ios/如果你不想这样做(这意味着重新制定所有约束),你可以在滚动视图内添加一个高度为0的视图,将其前导、尾随和顶部边缘约束设置为0,添加高度约束为0,然后在滚动视图和0高度视图之间添加等宽约束。是的,很奇怪,但是有效。 - Alex the Ukrainian
显示剩余3条评论

51

是的,我使用 scrollRectToVisible:animated: 时没有成功过,但 setContentOffset:animated: 总是能够正常工作。出于好奇,您为什么不想使用 setContentOffset:animated:?这似乎是正确的解决方案。


7
很遗憾,无论点是否可见,setContentOffset都会滚动到该点。我可以额外工作来确定该点是否可见,但是,当我在自己的示例和网络上看到它起作用时,我仍然很好奇为什么scrollRectToVisible不起作用。我一定做错了什么,但是由于scrollView只有三或四行代码,我看不出哪里错了?! - mahboudz

5

您可能需要检查并确认 scrollView 的 delaysContentTouches 属性设置为 NO

如果您从 scrollView 的子视图中的触摸调用方法 scrollRectToVisiblesetContentOffset,则 scrollView 可能会通过延迟触摸来阻塞操作。

因此,请确保在您的 scrollView 中设置以下内容。

scrollView.delaysContentTouches = NO;

你很可能可以通过设置是否使用动画来移动scrollView。


1

我之前是这样写的,但不起作用。

scrollView.contentSize = CGSizeMake(scrollView.contentSize.width, someKnownValue);

我只是改变了contentSize的高度,所以我并没有觉得会有什么问题,但实际上确实出现了问题...

不得不将它改成这样

scrollView.contentSize = CGSizeMake(someOtherKnownValue, someKnownValue);

原来scrollView.contentSize.width从一开始并没有被设置为有效值,所以最好给它一个具体的值。

0

如果您没有为“clefScrollView”设置框架,则上述建议的解决方案仍可能出现错误。

如果使用上述解决方案仍然遇到相同的问题,请确保在设置内容视图之前初始化您的滚动视图(在本例中为clefScrollView)框架。



    clefScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0,0,320,450)];

    [clefScrollView setContentSize:CGSizeMake(clefView.frame.size.width, clefView.frame.size.height)];




0
有点晚了,但我遇到了同样的问题。尽管我确信我的滚动视图内容大小设置正确 - 对于高度值来说甚至过多。即使进行了大量验证框架和内容大小的检查 - 仍然无法正常工作。我不得不调整“边界”框架高度,然后一切都运行良好。

0

我遇到了与此问题相同的症状...scrollRectToVisible没有按预期工作。我的问题是Storyboard上的滚动视图存在模糊约束问题。一旦解决了这个问题,调用就可以正常工作了。当scrollRectToVisible调用不能按预期工作时,还有其他要检查的地方。


0

对我来说问题在于子视图中的约束不明确。 检查你内容中的每个约束是否都设置好了,即使你显然不需要它来布局。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接