簡體   English   中英

UIScrollView 在 contentSize 變化時調整 contentOffset

[英]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包含UIScrollViewUINavigationController時發生。

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的屬性contentOffsetcontentInset 示例代碼:

- (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);

這對我有用:
在 storyboard 中,在 scrollView 的 Size Inspector 中,將 Content Insets Adjustment Behavior 設置為“Never”。

在此處輸入圖像描述

我遇到了這個問題,對於特定情況 - 我不調整大小 - 我使用了以下內容:

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 (由於導航欄等)所做的內容偏移調整的影響。

添加到KarenAnne的答案:

iOS 11+

不推薦使用automaticAdjustsScrollViewInsets

改用這個:

故事板:

在此處輸入圖像描述

代碼(斯威夫特):

scrollView.contentInsetAdjustmentBehavior = .never

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM