绑定会自动更改UIScrollView上的内容插入

时间:2014-05-06 06:20:56

标签: ios objective-c ios7 uiscrollview uiedgeinsets

我使用UIScrollView作为分页滚动视图pagesScrollView。在其中,我放置了专门用于缩放的单独UIScrollViews。在每个内部,我有一个视图,它是应该可缩放的页面项目。所有这些都在带有半透明导航栏的UINavigationController中。

我的pagesScrollViewcontentInset.top = 64bounds.origin.y = -64(这对我来说似乎很奇怪,但那是系统为我自动设置的内容),这很好用。我的屏幕看起来很棒!

但是,在我稍微滚动pagesScrollView之后,只要调出scrollViewWillEndDraggingpagesScrollView就会开始从bounds.origin.y = -64到{{1}的动画更改这导致我的页面项被导航栏遮挡。

左边是它加载时的样子,右边是我拖动几个像素后然后放开的样子,它在导航栏下滑动(因为bounds.origin.y去了到0)。

enter image description here

问题是我没有任何改变边界的代码,而且我在各种滚动委托方法中都没有任何代码可以做任何事情。我添加了一堆滚动委托方法,只是添加了NSLog(),所以我可以弄清楚发生变化的时间/地点,但是在我的代码中没有发生。

所以,我不知道我可以告诉你哪些代码可以帮助你。

编辑:我从头开始构建一个新项目以删除所有其他变量。我将一个裸UIViewController放入UINavigationController中。我将UIScrollView放入我的View中查看整个视图的大小。以下代码是整个项目。

事实证明,只有在UIScrollView上启用PAGING后才会出现问题(如下所述)!跆拳道? :)

这是一个下载基本项目的链接,只需几行代码即可演示此问题。只需单击滚动视图,您就会看到它随着边界的变化而向上移动。 http://inadaydevelopment.com/stackoverflow/WeirdScrollViews.zip

如何在我的滚动视图中启用分页,而不会在滚动和移动导航栏下的所有内容时突然出现限制?

可以将导航栏设置为不透明并避免出现问题,但理想的情况是具有标准的iOS7行为,以便在内容视图缩放后,然后允许内容位于导航栏下应该通过半透明正常显示。

bounds.origin.y = 0

5 个答案:

答案 0 :(得分:15)

只需关闭调整滚动视图插图

enter image description here

答案 1 :(得分:11)

这是一个iOS错误。我创建了以下UIScrollView的子类来记录y随着时间的推移会发生什么以及谁在推动它:

@implementation CSScrollView

- (void)setContentOffset:(CGPoint)contentOffset
{
    NSLog(@"%0.0f %@", contentOffset.y, [NSThread callStackSymbols]);
    NSLog(@"[%@]", self.layer.animationKeys);
    [super setContentOffset:contentOffset];
}

@end

(并更改了故事板中的视图类)

释放手指时,名为UIScrollView _smoothScrollDisplayLink:的方法会开始将滚动视图设置为最终位置。根据第二个日志,没有涉及CAAnimation,滚动视图使用自己的显示链接来进行自己的转换。该自定义代码似乎错误地将动画从y = whatever设置为y = 0,但未考虑内容偏移。

作为一个概念验证黑客,我将代码更改为:

@implementation CSScrollView

- (void)setContentOffset:(CGPoint)contentOffset
{
    contentOffset.y = -64.0f;
    [super setContentOffset:contentOffset];
}

@end

而且,不出所料,问题就消失了。

您可能不想对-64.0f进行硬编码,但我得出结论:

  • 这是一个iOS错误;
  • 通过UIScrollView的子类拒绝无意义的值并使用- setContentOffset:的合适自定义实现来解决此问题。

明智的通用方法可能是检查state的{​​{1}} - 这将允许您区分用户负责的滚动和其他滚动,而不依赖于任何未记录的API或复杂的代表事件捕获。然后,如果需要,从当前值中取出正确的self.panGestureRecognizer而不是硬编码。

答案 2 :(得分:0)

  

我的pagesScrollView有contentInset.top = 64和bounds.origin.y = -64(这对我来说似乎很奇怪,但这就是系统为我自动设置的),这很好用。我的屏幕看起来很棒!

因为iOS 7在所有滚动视图上将contentInset.top设置为64。 只需将这行代码添加到视图控制器中,所有代码都将按预期工作:

-(UIRectEdge)edgesForExtendedLayout {
return UIRectEdgeNone;

}

我检查了你的示例项目。

答案 3 :(得分:0)

我已经检查了你在viewController.m文件中使用以下代码的示例

-(void)viewDidLoad
{
    if ([[UIDevice currentDevice] systemVersion].floatValue>=7.0) {
        self.edgesForExtendedLayout = UIRectEdgeNone;
    }
}

它工作得很好......

答案 4 :(得分:0)

事实证明,问题(如下所述)仅在UIScrollView上启用PAGING后出现! WTF? :)

正如您所说,如果启用滚动分页,则UIScrollView将在框架承诺的拖动或任何移动后停在分页边缘。 Bounds.origin.y设置为零意味着第一页边缘与滚动视图框架边缘匹配,因为您在那里有64个contentInsets。因此,这不是错误,而是事实。而且由于栏是半透明的,因此请记住滚动视图的框架边缘在哪里,它在栏的下方。总之,我认为这不是错误,而是滚动分页的效果。