我有一个相当简单的视图配置:
UIViewController
,此UIScrollView
中有一个小孩UIImageView
和一个UIScrollView
。
我将UIImageView
设置为足以突破可见区域的高度(即更高到1024pt
),并将Bottom space to superview
的{{1}}约束设置为固定的正值(例如UIImageView
)。
整个设置按预期工作,图像在其父级中滚动得很好。 除非滚动视图(如果滚动到视图底部,效果更明显),然后消失,再次出现(您切换到另一个视图并返回)滚动值将恢复,但内容为滚动视图移动到其父视图的外部顶部。
这个解释起来并不简单,我会尝试绘制它:
如果您想测试/查看源(或故事板,我没有编辑一行代码)。我在我的github上放了一个小小的演示:https://github.com/guillaume-algis/iOSAutoLayoutScrollView
我确实阅读了iOS 6 changelog以及关于这个特定主题的解释,并认为这是第二个选项(纯自动布局)的正确实现,但在这种情况下,为什么20
表现得很好如此不规律?我错过了什么吗?
编辑:这与#12580434 uiscrollview-autolayout-issue完全相同。答案只是解决方法,因为任何人都找到了解决这个问题的正确方法,或者这是一个iOS错误吗?
编辑2 :我找到了另一种解决方法,它将滚动位置保持在用户离开的状态(这是对12580434已接受的答案的改进):
UIScrollView
这基本上保存了@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
中的值。问题似乎发生在这两个调用之间,但我无法找到它的起源。
答案 0 :(得分:22)
是的,UIScrollView在纯自动布局环境中发生了一些奇怪的事情。第二十次重新阅读iOS SDK 6.0 release notes我发现:
请注意,您可以通过在视图和滚动视图子树外部的视图之间创建约束(例如滚动视图的超级视图),使滚动视图的子视图显示为浮动(不滚动)其他滚动内容。
将子视图连接到外部视图。换句话说,就是嵌入了scrollview的视图。
由于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!它有效!
答案 1 :(得分:10)
编辑对我不起作用。但这有效:
-(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;
}
答案 2 :(得分:5)
对我来说,我去了IB点击了包含滚动视图的视图控制器。然后我去了属性检查员 - >视图控制器 - >延伸边缘 - >取消选中"在顶栏下#34;和"在底栏"。
答案 3 :(得分:2)
找到简单的解决方案,只需添加
[self setAutomaticallyAdjustsScrollViewInsets:NO];
ViewControllers中的viewDidLoad方法
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[self setAutomaticallyAdjustsScrollViewInsets:NO];
}
答案 4 :(得分:0)
我在UIViewController中使用UIScrollView时遇到了类似的问题,其中一个顶部额外空间在Storyboard中不可见。我的解决方案是取消选中ViewController故事板属性上的“调整滚动视图插图”:请参阅回答Extra Space (inset) in Scroll View at run time
答案 5 :(得分:-1)
添加全局属性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];
}
答案 6 :(得分:-4)
在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;
});
}