UIScrollView与自动布局错误的偏移量
我有一个相当简单的视图configuration:
一个UIViewController
,在这个UIScrollView
有一个子UIScrollView
和一个UIImageView
。 我设置了UIImageView
的高度足以突破可见区域(即高于1024pt
),并将Bottom space to superview
设置为我的UIImageView
1024pt
约束为固定的正值(例如20
)。
整个设置按预期工作,图像在其父项中很好地滚动。 除了滚动视图(如果滚动到视图的底部,效果更明显),然后消失,再次出现(切换到另一个视图并返回)滚动值将被恢复,但滚动的内容滚动视图移动到其父视图的外部顶部。
这不是简单的解释,我会试图画出来:
如果你想testing/查看来源(或故事板,我没有编辑一行代码)。 我在我的github上放了一个小样本: https : //github.com/guillaume-algis/iOSAutoLayoutScrollView
我没有阅读iOS 6 changelog和关于这个特定主题的解释,并认为这是第二个选项(纯自动布局)的正确实现,但在这种情况下,为什么UIScrollView
行为如此不正常? 我错过了什么吗?
编辑 :这是完全相同的问题#12580434 uiscrollview-autolayout问题 。 答案只是解决方法,任何人find一个正确的方法来解决这个问题,或者这是一个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
的值。 问题似乎发生在这两个电话之间,但是我找不到它的起源。
是的,在纯自动布局环境下,UIScrollView发生了一些奇怪的事情。 重读第二十次的iOS SDK 6.0发行说明 ,我发现:
请注意,您可以通过在视图和滚动视图的子树之外的视图(如滚动视图的超级视图)之间创build约束来使滚动视图的子视图浮动(不滚动)其他滚动内容。
解
将你的子视图连接到外部视图。 换句话说,就是embeddedscrollview的视图。
由于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! 有用!
编辑没有为我工作。 但是这工作:
-(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; }
对我来说,我去了IB点击我的视图控制器,其中包含滚动视图。 然后我去了属性检查器 – >视图控制器 – >扩展边缘 – >取消选中“顶部酒吧”和“底部酒吧”。
find简单的解决scheme,只要放
[self setAutomaticallyAdjustsScrollViewInsets:NO];
在你的ViewControllers的viewDidLoad方法中
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. [self setAutomaticallyAdjustsScrollViewInsets:NO]; }
我有一个类似的问题,在UIViewController中使用一个UIScrollView,在Storyboard中不可见的顶部额外空间。 对我来说,解决scheme是取消选中ViewController storyboard属性中的“Adjust Scroll View Insets”: 在运行时查看Scroll View中的额外空间(插入)
添加全局属性contentOffset,并将当前的contentOffset保存在viewDidDisappear中。 一旦你返回方法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]; }
看起来像在viewWillAppear:
期间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; }); }