更改框架时,UIScrollView更改contentOffset

时间:2014-02-14 18:55:40

标签: ios uiscrollview

当我更改滚动视图的框架时,我遇到了一些问题...有时这种改变会导致滚动,有时不会。

情况如下。我有一个自定义UIScrollView作为我的根视图控制器的子视图。 在父视图控制器中,我有一个按钮来更改scrollview的框架。它在屏幕的2/3和全屏之间切换。此帧更改永远不会导致scrollview的contentOffset发生更改。

在scrollview的内容中,我有一些按钮。此按钮也会更改scrollview的框架。 但是,有时候,这种变化会使scrollview改变其contentOffset ......

我无法弄清楚为什么scrollview中的按钮会导致这个......

我已经尝试在触摸按钮时调用代理(并在父视图控制器中更改scrollview框架)。 并尝试在滚动视图内更改框架(触摸按钮时)。但问题的出现方式相同。

知道这种情况发生了什么或有些解决方法吗?

谢谢!


我试图将这个问题与这里的一些简单示例隔离开来。

在我的xib中,只有一个带框架的滚动视图((20,44),(728,300))和一个调用事件“btnOut”的按钮。 该滚动视图启用了Paging Enabled和Autoresize Subviews(其余为默认值)。

我将使用布尔值来了解scrollview是否很大(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发生更改。

  • 如果scrollview在小框架中并且显示了列02并且我按下内部按钮则更改框架并显示列03和04(与按钮相同的操作在显示列02和03之外)。

嗯......我无法解释得那么好,所以当发生这种情况时我会举一个小例子。

2 个答案:

答案 0 :(得分:1)

我发现这是一个导致=>的私有方法。 _adjustContentOffsetIfNecessary

在某些情况下,它会改变偏移,而在其他情况下不会改变。就像我在我的例子中解释的那样。

如果禁用分页,则不调用私有方法以解决我的问题我创建了UIScrollView的子类并覆盖了方法touchesShouldBegin(仅当按下scrollView中的按钮时才会调用它)并禁用分页:

- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view {
    [self setPagingEnabled:NO];
    return YES;
}

要再次启用分页,我使用委托scrollViewWillBeginDragging

这样做,当我更改框架时,contentOffset不会改变,而scrollView继续使用分页。

答案 1 :(得分:-1)

以下是可能发生的事情:

假设您有一个带

的滚动视图
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  

并进行相同的更改,我认为滚动视图会尝试将其内容放入可见框架中,因此最终会出现

contentOffset.y      |    0

再次,有效地将其从100改为0.