ios 当 contentSize 改变时 UIScrollView 调整 contentOffset
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6523205/
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 adjusts contentOffset when contentSize changes
提问by Berik
I am adjusting a detail view controller's state, just before it is pushed on a navigationController
:
我正在调整详细视图控制器的状态,就在它被推送到一个之前navigationController
:
[self.detailViewController detailsForObject:someObject];
[self.navigationController pushViewController:self.detailViewController
animated:YES];
In the DetailViewController
a scrollView resides. Which content I resize based on the passed object:
在DetailViewController
一个滚动视图驻留。我根据传递的对象调整了哪些内容:
- (void)detailsForObject:(id)someObject {
// set some textView's content here
self.contentView.frame = <rect with new calculated size>;
self.scrollView.contentSize = self.contentView.frame.size;
self.scrollView.contentOffset = CGPointZero;
}
Now, this all works, but the scrollView adjusts it's contentOffset
during the navigationController's slide-in animation. The contentOffset
will be set to the difference between the last contentSize and the new calculated one. This means that the second time you open the detailsView, the details will scroll to some unwanted location. Even though I'm setting the contentOffset
to CGPointZero
explicitly.
现在,这一切都有效,但 scrollView 会contentOffset
在 navigationController 的滑入动画期间对其进行调整。在contentOffset
将被设置为最后contentSize和新计算之间的差异。这意味着第二次打开 detailsView 时,详细信息将滚动到一些不需要的位置。即使我明确设置contentOffset
为CGPointZero
。
I found that resetting the contentOffset
in - viewWillAppear
has no effect. The best I could come up with is resetting the contentOffset in viewDidAppear
, causing a noticeable up and down movement of the content:
我发现重置contentOffset
in- viewWillAppear
没有效果。我能想到的最好方法是重置 中的 contentOffset viewDidAppear
,导致内容明显的上下移动:
- (void)viewDidAppear:(BOOL)animated {
self.scrollView.contentOffset = CGPointZero;
}
Is there a way to prevent a UIScrollView
from adjusting its contentOffset
when its contentSize
is changed?
有没有办法防止 a在更改时对其进行UIScrollView
调整?contentOffset
contentSize
回答by KarenAnne
Occurs when pushing a UIViewController
containing a UIScrollView
using a UINavigationController
.
使用 a推送UIViewController
包含 a时发生。UIScrollView
UINavigationController
iOS 7
IOS 7
Solution 1 (Code)
解决方案1(代码)
Set @property(nonatomic, assign) BOOL automaticallyAdjustsScrollViewInsets
to NO
.
设置@property(nonatomic, assign) BOOL automaticallyAdjustsScrollViewInsets
为NO
。
Solution 2 (Storyboard)
解决方案 2(故事板)
Uncheck the Adjust Scroll View Insets
取消选中 Adjust Scroll View Insets
iOS 6
iOS 6
Solution (Code)
解决方案(代码)
Set the UIScrollView
's property contentOffset
and contentInset
in viewWillLayoutSubviews
. Sample code:
设置UIScrollView
的属性contentOffset
并contentInset
在viewWillLayoutSubviews
. 示例代码:
- (void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
self.scrollView.contentOffset = CGPointZero;
self.scrollView.contentInset = UIEdgeInsetsZero;
}
回答by Berik
The cause of this problem remains unclear, though I've found a solution. By resetting the content size and offset before adjusting them, the UIScrollView won't animate:
这个问题的原因仍然不清楚,但我已经找到了解决方案。通过在调整内容大小和偏移量之前重置它们,UIScrollView 不会动画:
- (void)detailsForObject:(id)someObject {
// These 2 lines solve the issue:
self.scrollView.contentSize = CGSizeZero;
self.scrollView.contentOffset = CGPointZero;
// set some textView's content here
self.contentView.frame = <rect with new calculated size>;
self.scrollView.contentSize = self.contentView.frame.size;
self.scrollView.contentOffset = CGPointZero;
}
回答by Eden
回答by Antoine
I had the same issue with a UIScrollview, where the problem was caused by not setting the contentSize. After setting the contentSize to the number of items this problem was solved.
我在 UIScrollview 上遇到了同样的问题,问题是由于未设置 contentSize 引起的。将 contentSize 设置为项目数后,这个问题就解决了。
self.headerScrollView.mainScrollview.contentSize = CGSizeMake(320 * self.sortedMaterial.count, 0);
回答by Slimebaron
I was experiencing a similar problem, where UIKit was setting the contentOffset of my scrollView during push animations.
我遇到了类似的问题,UIKit 在推送动画期间设置了我的 scrollView 的 contentOffset。
None of these solutions were working for me, maybe because I was supporting iOS 10 and iOS 11.
这些解决方案都不适合我,可能是因为我支持 iOS 10 和 iOS 11。
I was able to fix my issue by subclassing my scrollview to keep UIKit from changing my offsets after the scrollview had been removed from the window:
我能够通过子类化我的滚动视图来解决我的问题,以防止 UIKit 在滚动视图从窗口中删除后更改我的偏移量:
/// A Scrollview that only allows the contentOffset to change while it is in the window hierarchy. This can keep UIKit from resetting the `contentOffset` during transitions, etc.
class LockingScrollView: UIScrollView {
override var contentOffset: CGPoint {
get {
return super.contentOffset
}
set {
if window != nil {
super.contentOffset = newValue
}
}
}
}
回答by Balázs Csordás
I experienced the problem, and for a specific case - I don't adjust the size - I used the following:
我遇到了这个问题,对于特定情况 - 我不调整大小 - 我使用了以下内容:
float position = 100.0;//for example
SmallScroll.center = CGPointMake(position + SmallScroll.frame.size.width / 2.0, SmallScroll.center.y);
Same would work with y: anotherPosition + SmallScroll.frame.size.height / 2.0
同样适用于 y: anotherPosition + SmallScroll.frame.size.height / 2.0
So if you don't need to resize, this is a quick and painless solution.
因此,如果您不需要调整大小,这是一个快速且轻松的解决方案。
回答by octy
Is your scrollView the root view of the DetailViewController? If yes, try wrapping the scrollView in a plain UIView
and make the latter the root view of DetailViewController. Since UIView
s don't have a contentOffset
property, they are immune to content offset adjustments made by the navigation controller (due to the navigation bar, etc.).
你的 scrollView 是 DetailViewController 的根视图吗?如果是,请尝试将 scrollView 包装在一个普通的中UIView
,并使后者成为 DetailViewController 的根视图。由于UIView
s 没有contentOffset
属性,因此它们不受导航控制器所做的内容偏移调整的影响(由于导航栏等)。