UIScrollView 错误的偏移与自动布局

UIScrollView wrong offset with Auto Layout(UIScrollView 错误的偏移与自动布局)

本文介绍了UIScrollView 错误的偏移与自动布局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个相当简单的视图配置:

I have a fairly simple view configuration:

一个 UIViewController,在这个 UIScrollView 中有一个子 UIScrollView 和一个 UIImageView.我将 UIImageView 设置为足以突破可见区域的高度(即高于 1024pt),并将 Bottom 空间设置为 superview 我的 UIImageView 约束为一个固定的正值(例如 20).

A UIViewController, with a child UIScrollView and a UIImageView in this UIScrollView. I set the UIImageView with a height sufficient to break out of the visible area (ie. higher to 1024pt), and set the Bottom space to superview constraint of my UIImageView to a fixed positive value (20 for example).

整个设置按预期工作,图像在其父级中很好地滚动.除非当视图滚动时(滚动到视图底部效果更明显),然后消失,然后再次出现(您切换到另一个视图并回来)滚动值恢复,但内容滚动视图被移动到其父视图的外部顶部.

The whole setup works as expected, the image scrolls nicely in its parent. Except when the view is scrolled (the effect is more visible if you scrolled to the bottom of the view), then disappear, and appear again (you switched to another view and came back) the scrolling value is restored, but the content of the scroll view is moved to the outside top part of its parent view.

这个不好解释,我试着画一下:

This is not simple to explain, I'll try to draw it:

如果您想测试/查看源代码(或情节提要,我没有编辑任何一行代码).我在我的github上放了一个小demo:https://github.com/guillaume-algis/iOSAutoLayoutScrollView

If you want to test/view the source (or the storyboard, I did not edit a single line of code). I put a little demo on my github: https://github.com/guillaume-algis/iOSAutoLayoutScrollView

我确实阅读了 iOS 6changelog 和关于这个特定主题的解释,并认为这是第二个选项(纯自动布局)的正确实现,但在这种情况下,为什么 UIScrollView 的行为如此不规律?我错过了什么吗?

I did read the iOS 6 changelog and the explanation on this particular topic, and think this is the correct implementation of the second option (pure auto layout), but in this case why is the UIScrollView behaving so erratically ? Am I missing something ?

编辑:这与 #12580434 uiscrollview-autolayout-issue 完全相同的问题.答案只是变通方法,因为有人找到了解决此问题的正确方法,还是这是 iOS 错误?

EDIT: This is the exact same issue as #12580434 uiscrollview-autolayout-issue. The answers are just workarounds, as anyone found a proper way to fix this or is this a iOS bug ?

EDIT 2:我找到了另一种解决方法,它使滚动位置保持在用户离开它的相同状态(这是对 12580434 接受的答案):

EDIT 2: I found another workaround, which keep the scroll position in the same state the user left it (this is an improvement over 12580434's accepted answer):

@interface GAViewController ()

@property CGPoint tempContentOffset;

@end


@implementation GAViewController

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    self.tempContentOffset = self.mainScrollView.contentOffset;
    self.scrollView.contentOffset = CGPointZero;
}

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    self.scrollView.contentOffset = self.tempContentOffset;
}

这基本上保存了viewWillAppear中的偏移量,重置为原点,然后恢复viewDidAppear中的值.这两个调用之间似乎出现了问题,但我找不到它的起源.

This basically save the offset in viewWillAppear, reset it to the origin, and then restore the value in viewDidAppear. The problem seems to occur between these two calls, but I can't find its origin.

推荐答案

是的,UIScrollView 在纯自动布局环境中发生了一些奇怪的事情.重新阅读 iOS SDK 6.0 发行说明 我第二十次发现:

Yeah, something strange happened with UIScrollView in pure autolayout environment. Re-reading the iOS SDK 6.0 release notes for the twentieth time I found that:

请注意,您可以通过在视图和滚动视图的子树之外的视图(例如滚动视图的超级视图)之间创建约束,使滚动视图的子视图看起来浮动(不滚动)在其他滚动内容之上.

Note that you can make a subview of the scroll view appear to float (not scroll) over the other scrolling content by creating constraints between the view and a view outside the scroll view’s subtree, such as the scroll view’s superview.

解决方案

将您的子视图连接到外部视图.换句话说,就是嵌入了滚动视图的视图.

由于 IB 不允许我们在 imageView 和滚动视图子树之外的视图之间设置约束,例如滚动视图的超级视图,所以我已经在代码中完成了.

As IB does not allow us set up constraints between the imageView and a view outside the scroll view’s subtree, such as the scroll view’s superview then I've done it in code.

- (void)viewDidLoad {
    [super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
    [self.view removeConstraints:[self.view constraints]];
    [self.scrollView removeConstraints:[self.scrollView constraints]];
    [self.imageView removeConstraints:[self.imageView constraints]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[_scrollView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_scrollView)]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_scrollView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_scrollView)]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[_imageView(700)]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_imageView)]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_imageView(1500)]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_imageView)]];
}

还有 vau!有效!

这篇关于UIScrollView 错误的偏移与自动布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:UIScrollView 错误的偏移与自动布局

基础教程推荐