UIScrollView ScrollRectToVisible - 不适用于 animate = yes
Posted
技术标签:
【中文标题】UIScrollView ScrollRectToVisible - 不适用于 animate = yes【英文标题】:UIScrollView ScrollRectToVisible - not working with animate = yes 【发布时间】:2011-08-23 23:36:00 【问题描述】:我有一个包含按钮的 UIScrollView。 当按下按钮时,我想使用 scrollRectToVisible 滚动到视图的底部。
例如:
CGRect r = CGRectMake(0, myUIScrollView.contentSize.height - 1, 1, 1);
[myUIScrollView scrollRectToVisible:r animated:YES];
如果我将动画设置为 NO,一切都会按预期进行, 但如果我将其设置为 YES,我会看到非常奇怪的行为:
基本上没有任何反应。 如果我反复点击按钮,它可能会滚动几个像素, 或者可以一直滚动。 但如果我在按下按钮之前用手指手动滚动视图, 它有可能按预期滚动到底部,但这不是确定的。我已经打印了 _geScroll_Settings.contentSize,结果符合预期。
我还尝试通过启动计时器来延迟对 scrollRectToVisible 的调用,但结果几乎相同。
scrollView 相当普通。 我在界面生成器中创建它。 我在启动时动态添加滚动视图的内容,并适当调整它的 contentSize,但一切似乎都工作正常。
有什么想法吗?
【问题讨论】:
还没有弄清楚,但我必须完成它,所以我只是启动了一个计时器并自己滚动它,直到它在正确的位置,使用 setContentOffset w/animated:NO。有效,但是:( 【参考方案1】:我敢打赌,scrollRectToVisible 因为可见区域无效 (1x1) 或 y 偏移量 刚好在边界之外,所以你尝试将其设置为可见区域的大小而不是滚动视图的区域?
CGRect rectBottom = CGRectZero;
rectBottom.size = myUIScrollView.frame.size;
rectBottom.origin.y = myUIScrollView.contentSize.height - rectBottom.size.height;
rectBottom.origin.x = 0;
[myUIScrollView scrollRectToVisible:rectBottom animated:YES];
抱歉,我无法为您提供更多帮助,但我现在不在我的 Mac 上,所以我无法运行测试。上面的代码将创建一个 CGRect,其大小与 scrollView 可见部分的大小完全相同,并且偏移量将是其中的最后一个可见部分。
【讨论】:
有趣。我会试一试,但我很怀疑。我确实使用了更正常大小的矩形 - 例如滚动视图的宽度和大于一但小于滚动视图高度的一些高度,但没有什么不同。还尝试了在 contentSize 中间而不是在末尾的矩形。我会告诉你。顺便说一句,我不知道 CGRectZero,谢谢! 刚刚回复你这个问题 - 我试过了,但没有运气。我最终通过使用“动画:否”和计时器自己制作了动画。无论如何,谢谢。 我刚刚遇到了这个问题。花了大约 2 个小时查看所有内容但 scrollRectToVisible 调用。【参考方案2】:我遇到了类似的问题,包括“如果我将动画设置为 NO,一切都会按预期工作”部分。
事实证明,在 ios 6 上,UITextView 会自动滚动其最近的父 UIScrollView,以使光标在成为第一响应者时可见。在 iOS 7 上没有这样的行为。 UIScrollView 似乎被两个同时调用 scrollRectToVisible 弄糊涂了。
在 iOS 6 上,我对 scrollRectToVisible 的显式调用在大部分时间被忽略。它只会滚动以使 UITextView 的第一行可见(自动滚动),而不是像在 iOS 7 上所做的那样。
要对其进行测试,请在 Xcode 5 中创建一个新的单视图应用程序,将其部署目标设置为 6.0,并将以下代码用于 ViewController.m。在 iOS 6.1 模拟器中运行它,滚动以隐藏 UITextView,然后点击屏幕上的任意位置。您可能需要重试几次,但在大多数情况下,它只会使第一行可见。如果您重新启用 WORKAROUD 定义,则 UITextView 将嵌入到它自己的 UIScrollView 中,并且对 scrollRectToVisible 的调用按预期工作。
#import "ViewController.h"
//#define WORKAROUND
@interface ViewController ()
@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UITextView *textView;
@end
@implementation ViewController
- (void)viewDidLoad
[super viewDidLoad];
[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(viewTap)]];
self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 240)];
self.scrollView.contentSize = CGSizeMake(320, 400);
self.scrollView.backgroundColor = [UIColor lightGrayColor];
[self.view addSubview:self.scrollView];
#ifdef WORKAROUND
UIScrollView* dummyScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(20, 280, 280, 100)];
self.textView = [[UITextView alloc] initWithFrame:dummyScrollView.bounds];
[dummyScrollView addSubview:self.textView];
[self.scrollView addSubview:dummyScrollView];
#else
self.textView = [[UITextView alloc] initWithFrame:CGRectMake(20, 280, 280, 100)];
[self.scrollView addSubview:self.textView];
#endif
self.textView.backgroundColor = [UIColor grayColor];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil];
- (void)dealloc
[[NSNotificationCenter defaultCenter] removeObserver:self];
- (void)viewTap
if (self.textView.isFirstResponder)
[self.textView resignFirstResponder];
else
[self.textView becomeFirstResponder];
- (void)keyboardWasShown:(NSNotification*)aNotification
#ifdef WORKAROUND
[self.scrollView scrollRectToVisible:CGRectInset(self.textView.superview.frame, 0, -10) animated:YES];
#else
[self.scrollView scrollRectToVisible:CGRectInset(self.textView.frame, 0, -10) animated:YES];
#endif
@end
【讨论】:
以上是关于UIScrollView ScrollRectToVisible - 不适用于 animate = yes的主要内容,如果未能解决你的问题,请参考以下文章
UIScrollView里面的UIScrollView:滚动
问题:UIScrollview 弹跳使父 UIScrollview 弹跳
UIScrollView 嵌入其他 UIScrollView