[英]UIScrollView adjusts contentOffset when contentSize changes
我正在調整詳細視圖控制器的 state,就在它被推送到navigationController
之前:
[self.detailViewController detailsForObject:someObject];
[self.navigationController pushViewController:self.detailViewController
animated:YES];
在DetailViewController
中有一個 scrollView 駐留。 我根據傳遞的 object 調整了哪些內容:
- (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;
}
現在,這一切都有效,但是在 navigationController 的滑入 animation 期間,scrollView 會調整它的contentOffset
。 contentOffset
將設置為最后一個 contentSize 和新計算的值之間的差異。 這意味着第二次打開 detailsView 時,詳細信息將滾動到某個不需要的位置。 即使我將contentOffset
明確設置為CGPointZero
。
我發現在- viewWillAppear
中重置contentOffset
沒有效果。 我能想到的最好辦法是在viewDidAppear
中重置 contentOffset,從而導致內容明顯上下移動:
- (void)viewDidAppear:(BOOL)animated {
self.scrollView.contentOffset = CGPointZero;
}
有沒有辦法防止UIScrollView
在其contentSize
更改時調整其contentOffset
?
使用UIViewController
包含UIScrollView
的UINavigationController
時發生。
iOS 11+
解決方案 1(Swift 代碼):
scrollView.contentInsetAdjustmentBehavior = .never
解決方案 2(故事板)
iOS 7
解決方案 1(代碼)
將@property(nonatomic, assign) BOOL automaticallyAdjustsScrollViewInsets
設置為NO
。
解決方案 2(故事板)
取消選中Adjust Scroll View Insets
iOS 6
解決方案(代碼)
在viewWillLayoutSubviews
中設置UIScrollView
的屬性contentOffset
和contentInset
。 示例代碼:
- (void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
self.scrollView.contentOffset = CGPointZero;
self.scrollView.contentInset = UIEdgeInsetsZero;
}
盡管我找到了解決方案,但此問題的原因仍不清楚。 通過在調整它們之前重置內容大小和偏移量,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;
}
我在 UIScrollview 上遇到了同樣的問題,問題是由於未設置 contentSize 引起的。 將 contentSize 設置為項目數后,此問題已解決。
self.headerScrollView.mainScrollview.contentSize = CGSizeMake(320 * self.sortedMaterial.count, 0);
我遇到了這個問題,對於特定情況 - 我不調整大小 - 我使用了以下內容:
float position = 100.0;//for example
SmallScroll.center = CGPointMake(position + SmallScroll.frame.size.width / 2.0, SmallScroll.center.y);
同樣適用於 y: anotherPosition + SmallScroll.frame.size.height / 2.0
因此,如果您不需要調整大小,這是一個快速而輕松的解決方案。
我遇到了類似的問題,其中 UIKit 在推送動畫期間設置了我的 scrollView 的 contentOffset。
這些解決方案都不適合我,可能是因為我支持 iOS 10 和 iOS 11。
在從 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
}
}
}
}
你的 scrollView 是 DetailViewController 的根視圖嗎? 如果是,請嘗試將 scrollView 包裝在普通的UIView
中,並使后者成為 DetailViewController 的根視圖。 由於UIView
沒有contentOffset
屬性,因此它們不受導航 controller (由於導航欄等)所做的內容偏移調整的影響。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.