UIScrollView的错自动布局偏移(UIScrollView wrong offset wit

2019-07-21 08:26发布

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

一个UIViewController ,有一个孩子UIScrollViewUIImageView在这个UIScrollView 。 我设置UIImageView有足够的打出来的可见区域(即更高的高度1024pt ),并设置Bottom space to superview我约束UIImageView到一个固定的正值( 20为例)。

整个安装工程如预期,图像很好地滚动在其父。 除了当视图被滚动(效果更明显,如果您滚动到视图的底部),然后消失,再次出现(你切换到另外的看法,回来)滚动值恢复,但对内容滚动视图被移动到它的父视图的外侧顶部部分。

这不是简单的解释,我会尽力把它画:

如果你想测试/查看源(或故事板,我没有编辑的一行代码)。 我把一个小演示在我github上: https://github.com/guillaume-algis/iOSAutoLayoutScrollView

我看过了iOS 6的更新日志 ,并在此特定主题的解释,并认为这是正确的实现第二个选项(自动纯布局),但在这种情况下,为什么是UIScrollView表现如此不稳定? 我缺少的东西吗?

编辑 :这是完全一样的问题,因为#12580434的UIScrollView,自动布局-问题 。 这些问题的答案都只是解决方法,因为任何人都找到了适当的方式来解决这个或者这是一个错误的iOS?

编辑2:我发现了另外一个解决方法,它在保持用户离开时的相同状态滚动位置(这是在改善12580434的接受的答案):

@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 。 这个问题似乎这两个调用之间发生,但我找不到它的起源。

Answer 1:

是啊,奇怪的事情发生与UIScrollView的纯自动布局环境。 重读的iOS SDK 6.0版本说明第二十次我发现:

请注意,您可以滚动视图的子视图出现通过创建视图和滚动视图的子树,外视图之间的约束,如滚动视图的上海华浮动(不滚动)比其他滚动内容。

你的子视图连接到外视图。 换句话说,向图,其中滚动视图嵌入。

由于IB不容许我们建立的ImageView和滚动视图的子树,外视图之间的约束,如滚动视图的上海华盈,我已经在代码中完成它。

- (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! 有用!



Answer 2:

编辑并没有为我工作。 但是这个工作:

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

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

- (void)viewDidLayoutSubviews {
     [super viewDidLayoutSubviews];
     self.scrollView.contentOffset = self.tempContentOffset;
}


Answer 3:

对我来说,我去了IB点击包含滚动查看我的视图控制器。 然后我去属性检查器 - >视图 - 控制器 - >扩展边缘 - >取消选中“在热门酒吧”和“在底部的酒吧”。



Answer 4:

简单的解决方案发现,只要把

[self setAutomaticallyAdjustsScrollViewInsets:NO];

在ViewControllers viewDidLoad方法

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.

    [self setAutomaticallyAdjustsScrollViewInsets:NO];
}


Answer 5:

我使用一个UIViewController一个UIScrollView与顶部额外的空间,在故事板是不可见的类似的问题。 对我来说,解决办法是取消对故事板视图控制器属性中的“调整滚动查看插图”:看回答额外的空间(插图)中滚动查看在运行时



Answer 6:

添加一个全局属性contentOffset并保存在viewDidDisappear当前contentOffset。 一旦你返回方法viewDidLayoutSubviews将被调用,您可以将原始contentOffset。

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    [self.scrollView setContentOffset:self.contentOffset animated:FALSE];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
    self.contentOffset = self.scrollView.contentOffset;
    [self.scrollView setContentOffset:CGPointMake(0, 0) animated:FALSE];
}


Answer 7:

貌似与解决的问题dispatch_async期间viewWillAppear:

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

    CGPoint originalContentOffset = self.scrollView.contentOffset;
    self.scrollView.contentOffset = CGPointZero;

    dispatch_async(dispatch_get_main_queue(), ^{
        self.scrollView.contentOffset = originalContentOffset;
    });
}


文章来源: UIScrollView wrong offset with Auto Layout