UIScrollView 更改 contentOffset 时更改框架
Posted
技术标签:
【中文标题】UIScrollView 更改 contentOffset 时更改框架【英文标题】:UIScrollView change contentOffset when change frame 【发布时间】:2014-02-14 18:55:40 【问题描述】:我在更改滚动视图的框架时遇到了一些问题...有时这种更改会导致滚动,有时不会。
情况是这样的。我有一个自定义 UIScrollView 作为我的根视图控制器的子视图。 在父视图控制器中,我有一个按钮来更改滚动视图的框架。它在屏幕的 2/3 和全屏之间切换。此帧更改不会导致滚动视图的 contentOffset 发生更改。
在滚动视图的内容中,我有一些按钮。这个按钮也改变了滚动视图的框架。 但是,有时,此更改会使滚动视图更改其 contentOffset...
我不明白为什么滚动视图中的按钮会导致这个...
我已经尝试在触摸按钮时调用委托(并在父视图控制器中更改滚动视图的框架)。 并试图改变滚动视图内的框架(当按钮被触摸时)。但问题发生的方式相同。
知道发生了什么或解决这种情况的方法吗?
谢谢!
我试图隔离问题,在这里放一些简单的代码示例。
在我的 xib 中只有一个带有框架 ((20,44),(728,300)) 的滚动视图和一个调用事件“btnOut”的按钮。 该滚动视图启用了分页并禁用了自动调整子视图(其余为默认值)。
我将使用布尔值来判断滚动视图是否大(bigScroll)。
这是我的 viewDidLoad:
- (void)viewDidLoad
[super viewDidLoad];
// the initial frame of scrollView is the big frame
_bigScroll = YES;
// here I put a big content to create some pages in scrollView
[_scrollView setContentSize:CGSizeMake(2184, 300)];
// I put one button in each column
// When scrollView is with big frame it shows two columns and when it is with small frame it shows only one column.
UIButton *btn01 = [UIButton buttonWithType:UIButtonTypeSystem];
[btn01 setFrame:CGRectMake(159, 30, 46, 30)];
[btn01 setTitle:@"01" forState:UIControlStateNormal];
[btn01 addTarget:self action:@selector(btnIn:) forControlEvents:UIControlEventTouchDown];
[_scrollView addSubview:btn01];
UIButton *btn02 = [UIButton buttonWithType:UIButtonTypeSystem];
[btn02 setFrame:CGRectMake(523, 30, 46, 30)];
[btn02 setTitle:@"02" forState:UIControlStateNormal];
[btn02 addTarget:self action:@selector(btnIn:) forControlEvents:UIControlEventTouchDown];
[_scrollView addSubview:btn02];
UIButton *btn03 = [UIButton buttonWithType:UIButtonTypeSystem];
[btn03 setFrame:CGRectMake(887, 30, 46, 30)];
[btn03 setTitle:@"03" forState:UIControlStateNormal];
[btn03 addTarget:self action:@selector(btnIn:) forControlEvents:UIControlEventTouchDown];
[_scrollView addSubview:btn03];
UIButton *btn04 = [UIButton buttonWithType:UIButtonTypeSystem];
[btn04 setFrame:CGRectMake(1251, 30, 46, 30)];
[btn04 setTitle:@"04" forState:UIControlStateNormal];
[btn04 addTarget:self action:@selector(btnIn:) forControlEvents:UIControlEventTouchDown];
[_scrollView addSubview:btn04];
UIButton *btn05 = [UIButton buttonWithType:UIButtonTypeSystem];
[btn05 setFrame:CGRectMake(1615, 30, 46, 30)];
[btn05 setTitle:@"05" forState:UIControlStateNormal];
[btn05 addTarget:self action:@selector(btnIn:) forControlEvents:UIControlEventTouchDown];
[_scrollView addSubview:btn05];
UIButton *btn06 = [UIButton buttonWithType:UIButtonTypeSystem];
[btn06 setFrame:CGRectMake(1979, 30, 46, 30)];
[btn06 setTitle:@"06" forState:UIControlStateNormal];
[btn06 addTarget:self action:@selector(btnIn:) forControlEvents:UIControlEventTouchDown];
[_scrollView addSubview:btn06];
“btnIn”和“btnOut”两个动作调用相同的函数 (changeFrameScrollView)。
- (void)changeFrameScrollView
_bigScroll = !_bigScroll;
if (_bigScroll)
[_scrollView setFrame:CGRectMake(20, 44, 728, 300)];
else
[_scrollView setFrame:CGRectMake(20, 44, 364, 300)];
我的预期: 使用滚动视图之外的按钮,框架更改按我的预期工作。
如果更改为小框架,则会从右侧隐藏该列并继续从左侧显示该列。 如果它变成大框架,它会从右侧显示列并且不要移动 contentOffset。** 独立于我正在查看的页面。
问题: 有时,使用滚动视图内的按钮,框架更改会导致 contentOffset 发生更改。
嗯...我不能解释得这么好,所以我举了一个小例子。
【问题讨论】:
也许一些代码会有所帮助。另外,描述内容偏移量的变化。 【参考方案1】:我发现这是导致该问题的私有方法 => _adjustContentOffsetIfNecessary
它在某些情况下会改变偏移量,而在其他情况下不会改变。就像我在示例中解释的那样。
如果禁用分页,则不会调用该私有方法,因此为了解决我的问题,我创建了 UIScrollView 的子类并覆盖方法 touchesShouldBegin
(仅在按下 scrollView 内的按钮时调用)并禁用分页:
- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view
[self setPagingEnabled:NO];
return YES;
要再次启用分页,我使用委托scrollViewWillBeginDragging
。
这样做,当我更改框架时 contentOffset 不会改变,并且 scrollView 继续使用分页。
【讨论】:
【参考方案2】:以下是可能发生的情况:
假设你有一个带有
的滚动视图contentSize.height | 200
frame.size.height | 100
contentOffset.y | 0
那么一半的内容将是不可见的。如果你改变frame
frame.size height | 200
contentOffset
不应更改。
但是,如果您以
开头contentSize.height | 200
frame.size.height | 100
contentOffset.y | 100
并做同样的改变,我想滚动视图会尝试将其内容放入可见框架中,所以你最终会得到 p>
contentOffset.y | 0
再次,有效地将其从 100 更改为 0。
【讨论】:
在这种情况下,更改是可以接受的,因为它没有更多可显示的内容,因此它调整 contentOffset 以适应可见框架,如您所说。但在我的情况下,调整发生在内容的中间......而且我无法理解。我放了一些代码来显示正在发生的事情。感谢您的关注!以上是关于UIScrollView 更改 contentOffset 时更改框架的主要内容,如果未能解决你的问题,请参考以下文章
UIScrollView 更改 contentOffset 时更改框架