ios 弹回 UIViewController 后 UIScrollView 的原点发生变化
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17404682/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
UIScrollView's origin changes after popping back to the UIViewController
提问by Peter Jacobs
I have a UIViewController
subclass as a scene in the storyboard that contains a UIScrollView
containing various subviews. One of the subviews is a UIButton
which segues into another scene UIViewController
subclass. When I come back from the view (pop the UIViewController
off the navigation controller stack), I find that the scroll view's origin has somehow changed, although the contentsize
and contentoffset
seem correct.
我有一个UIViewController
子类作为故事板中的一个场景,其中包含一个UIScrollView
包含各种子视图的场景。其中一个子视图是UIButton
转入另一个场景UIViewController
子类的 a 。当我从视图中返回(从UIViewController
导航控制器堆栈中弹出)时,我发现滚动视图的原点以某种方式发生了变化,尽管contentsize
和contentoffset
看起来是正确的。
What's also interesting is that the app has a tab bar, and when I tab away and back to that view, the scroll view is set back correctly with offset at (0, 0).
同样有趣的是,该应用程序有一个标签栏,当我离开并返回该视图时,滚动视图正确设置为偏移量在 (0, 0)。
There is basically no code involved in this process, as it's pretty much all in the storyboard. As I am fairly new to using the storyboard, I figure I'm doing something wrong, although I don't know what. Any ideas as to what that may be? Perhaps sizing issues or constraints?
这个过程基本上不涉及任何代码,因为它几乎都在故事板中。由于我对使用故事板还很陌生,我认为我做错了什么,尽管我不知道是什么。关于这可能是什么的任何想法?也许是尺寸问题或限制?
采纳答案by Peter Jacobs
Actually, I put that line of code in viewDidDisappear
, and so that it remembers the offset when the view reappears, I added this line before it
实际上,我将那行代码放在 中viewDidDisappear
,以便它在重新出现视图时记住偏移量,我在它之前添加了这一行
self.contentOffset = self.scrollView.contentOffset;
as well as
也
- (void)viewDidLayoutSubviews {
self.scrollView.contentOffset = self.contentOffset;
}
回答by Alex
In iOS 7/8/9 simple self.automaticallyAdjustsScrollViewInsets = NO;
solved the problem in my case.
在 iOS 7/8/9 中简单self.automaticallyAdjustsScrollViewInsets = NO;
解决了我的问题。
回答by MacMark
Try this in viewWillAppear of the view controller you pop back into:
在你弹回的视图控制器的 viewWillAppear 中试试这个:
self.scrollView.contentOffset = CGPointMake(0, 0);
Edit: When also adding Peter's code you get the best results with:
编辑:同时添加彼得的代码时,您会获得最佳结果:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:YES];
self.scrollView.contentOffset = CGPointMake(0, 0);
}
plus
加
- (void)viewWillDisappear:(BOOL)animated {
self.recentContentOffset = self.scrollView.contentOffset;
[super viewWillDisappear:animated];
}
and
和
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
self.scrollView.contentOffset = CGPointMake(0, self.recentContentOffset.y);
}
You return to the original scroll position, have no visual side-effect and the scroll view itself is correctly positioned in its superview (which was a problem) after coming back.
您返回到原始滚动位置,没有视觉副作用,并且返回后滚动视图本身正确定位在其超级视图中(这是一个问题)。
回答by Chuy47
i had a similar problem, after dismissing a viewController, the contentOffset from my tableView was changed to (0, -64).
我有一个类似的问题,在关闭 viewController 后,我的 tableView 的 contentOffset 被更改为 (0, -64)。
my solution was a little weird, i tried all the other answers but had no success, the only thing that fixed my problem was to switch the tableView position in the controls tree of the .xib
我的解决方案有点奇怪,我尝试了所有其他答案但没有成功,解决我的问题的唯一方法是在 .xib 的控件树中切换 tableView 位置
it was the first control in the parent View like this:
它是父视图中的第一个控件,如下所示:
I moved the tableView right after the ImageView and it worked:
我在 ImageView 之后立即移动了 tableView 并且它起作用了:
it seems that putting the table view in the first position was causing the trouble, and moving the table view to another position fixed the problem.
似乎将 table view 放在第一个位置引起了麻烦,将 table view 移动到另一个位置可以解决问题。
P.D. I'm not using autoLayout neither storyboards
PD 我没有使用 autoLayout 也没有故事板
hope this can help someone!
希望这可以帮助某人!
回答by Joseph Francis
I'm using a collectionView and I had a similar problem. For iOS 11: in the size inspector, there is "content inset". Set that to "Never". That solved the problem for me. I hope this helps someone.
我正在使用 collectionView 并且我遇到了类似的问题。对于 iOS 11:在大小检查器中,有“内容插入”。将其设置为“从不”。那为我解决了问题。我希望这可以帮助别人。
Objective C:
目标 C:
if (@available(iOS 11, *)) {
[UIScrollView appearance].contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
Swift:
迅速:
if #available(iOS 11, *) {
UIScrollView.appearance().contentInsetAdjustmentBehavior = .never
}
回答by Nithin
In iOS 11, I faced a similar issue where when I come back after popping a view controller, the tableview in the previous viewcontroller used to adjust its content inset automatically which resulted in tableview contents jumping from top abruptly. The following solution worked for me in iOS 11.
在 iOS 11 中,我遇到了类似的问题,当我在弹出视图控制器后返回时,之前的视图控制器中的 tableview 用于自动调整其内容插入,导致 tableview 内容突然从顶部跳转。以下解决方案在 iOS 11 中对我有用。
In Storyboard, select the tableview and go to Attributes inspector and uncheck "Automatic" for Row Height and Estimate fields. Also change the content insets from "Automatic" to "Never".
在 Storyboard 中,选择 tableview 并转到 Attributes inspector 并取消选中 Row Height 和 Estimate 字段的“Automatic”。还将内容插入从“自动”更改为“从不”。
[]
[ ]
回答by Kyle Clegg
Unfortunately, Peter and MacMark's suggestions did not work for me (Xcode 5 w/ auto-layout). The solution was to go to the storyboard, select the view controller, and Reset to Suggested Constraints in View Controller
.
不幸的是,Peter 和 MacMark 的建议对我不起作用(Xcode 5 w/ auto-layout)。解决方案是转到故事板,选择视图控制器,然后Reset to Suggested Constraints in View Controller
.
回答by bilobatum
I posted a question recently about a similar issue but in a different context: Frame doesn't reflect auto layout constraints after dismissing modal view controller
我最近发布了一个关于类似问题但在不同上下文中的问题: 在关闭模态视图控制器后,框架不反映自动布局约束
In my case, the origin of a custom container view inside the scroll view is displaced, rather than the origin of the scroll view itself. With respect to auto layout, the custom container view is pinned to the four sides of the scroll view.
在我的情况下,滚动视图内自定义容器视图的原点被置换,而不是滚动视图本身的原点。关于自动布局,自定义容器视图固定在滚动视图的四个侧面。
The container view is created and configured programmatically rather than in IB. Although the constraints of the container view are unchanged, the container view's origin is displaced after dismissing a modal view controller. This disconnect between constraints and frames is inexplicable.
容器视图是以编程方式而不是在 IB 中创建和配置的。尽管容器视图的约束没有改变,但在解除模态视图控制器后,容器视图的原点发生了位移。约束和框架之间的这种脱节是无法解释的。
What's even more remarkable is that the origin displacement problem remained after I removed and re-added all related constraints.
更值得注意的是,在我删除并重新添加所有相关约束后,原点位移问题仍然存在。
I came up with a similar solution: save the value for the current content offset, set the content offset to "zero", let the system swap out your views, then restore the content offset (i.e., a content-offset dance).
我想出了一个类似的解决方案:保存当前内容偏移的值,将内容偏移设置为“零”,让系统换出您的视图,然后恢复内容偏移(即内容偏移舞蹈)。
In my case, however, I had to take additional steps to resolve the issue. My scroll view is a paging scroll view that gets its subviews from a tilePages method (demoed in an old WWDC video). Changing the scroll view's content offset triggers the tilePages method via the UIScrollViewDelegate's scrollViewDidScroll: method. I had to set a flag to turn off tilePages while I did the content-offset dance, otherwise the app would crash.
但是,就我而言,我必须采取其他步骤来解决该问题。我的滚动视图是一个分页滚动视图,它从 tilePages 方法(在旧的 WWDC 视频中演示)获取其子视图。更改滚动视图的内容偏移会通过 UIScrollViewDelegate 的 scrollViewDidScroll: 方法触发 tilePages 方法。在进行内容偏移舞蹈时,我必须设置一个标志来关闭 tilePages,否则应用程序会崩溃。
Hopefully, I can remove the code for the content-offset dance when I upgrade to iOS 7.
希望我可以在升级到 iOS 7 时删除内容偏移舞蹈的代码。
回答by ChrisHaze
Continued Issue when following the current answers:
遵循当前答案时的继续问题:
The second attempt to open the presented view controller, without having left the presenting view controller, the problem remained. Which is why I am posting the exact stepsthat resulted in my solution.
第二次尝试打开呈现的视图控制器,没有离开呈现的视图控制器,问题仍然存在。这就是为什么我要发布导致我的解决方案的确切步骤。
So, I resetthe collectionView's constraints in the Storyboard, making certain they were pinned to presentingViewController's main view.
Added:
self.view.translatesAutoresizingMaskIntoConstraints = YES;
inside theviewDidLoad
of the presenting view controller.And stored, privately, the contentOffset of the collection view prior to the modally presented view controller's appearance:
(void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; self.contentOffset = self.collectionView.contentOffset; self.collectionView.contentOffset = CGPointZero; } - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; self.collectionView.contentOffset = self.contentOffset; }
因此,我在 Storyboard 中重置了 collectionView 的约束,确保它们被固定到presentingViewController 的主视图中。
添加:
self.view.translatesAutoresizingMaskIntoConstraints = YES;
在viewDidLoad
呈现视图控制器的内部。并在模态呈现的视图控制器出现之前私下存储集合视图的 contentOffset :
(void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; self.contentOffset = self.collectionView.contentOffset; self.collectionView.contentOffset = CGPointZero; } - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; self.collectionView.contentOffset = self.contentOffset; }
回答by Trouble maker
recently , I have encountered this bug, can be solved using these codes:
最近,我遇到了这个bug,可以用这些代码解决:
// fix ios 6 bug begin
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 7) {
isRecoredforios6 = YES;
recordedOffsetforios6 = self.tableView.contentOffset;
recordedSizeforios6 = self.tableView.contentSize;
}
}
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
if (isRecoredforios6) {
isRecoredforios6 = NO;
self.tableView.contentSize = recordedSizeforios6;
self.tableView.contentOffset = recordedOffsetforios6;
}
}
// fix ios 6 bug end
thanks Peter Jacobs!
感谢彼得·雅各布斯!