web-dev-qa-db-ja.com

contentScrollが変更されると、UIScrollViewはcontentOffsetを調整します

navigationControllerにプッシュされる直前に、詳細ビューコントローラーの状態を調整しています。

[self.detailViewController detailsForObject:someObject];
[self.navigationController pushViewController:self.detailViewController
                                     animated:YES];

DetailViewControllerにはscrollViewが存在します。渡されたオブジェクトに基づいてサイズを変更するコンテンツ:

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

これですべて動作しますが、sScrollViewはnavigationControllerのスライドインアニメーション中にcontentOffsetを調整します。 contentOffsetは、最後のcontentSizeと新しく計算されたcontentSizeの差に設定されます。つまり、detailsViewを2回目に開くと、詳細は不要な場所にスクロールします。 contentOffsetCGPointZeroに明示的に設定していますが。

- viewWillAppearcontentOffsetをリセットしても効果がないことがわかりました。私が思いついた最善の方法は、viewDidAppearのc​​ontentOffsetをリセットし、コンテンツの顕著な上下運動を引き起こすことです:

- (void)viewDidAppear:(BOOL)animated {
    self.scrollView.contentOffset = CGPointZero;
}

UIScrollViewが変更されたときに、contentOffsetcontentSizeを調整するのを防ぐ方法はありますか?

36
Berik

UIViewControllerを使用してUIScrollViewを含むUINavigationControllerをプッシュするときに発生します。

iOS 7

ソリューション1(コード)

@property(nonatomic, assign) BOOL automaticallyAdjustsScrollViewInsetsNOに設定します。

ソリューション2(ストーリーボード)

Adjust Scroll View Insets

Adjust Scroll View Insets

iOS 6

ソリューション(コード)

UIScrollViewcontentOffsetのプロパティcontentInsetおよびviewWillLayoutSubviewsを設定します。サンプルコード:

- (void)viewWillLayoutSubviews{
  [super viewWillLayoutSubviews];
  self.scrollView.contentOffset = CGPointZero;
  self.scrollView.contentInset = UIEdgeInsetsZero;
}
58
KarenAnne

私は解決策を見つけましたが、この問題の原因は不明のままです。コンテンツを調整する前にコンテンツのサイズとオフセットをリセットすると、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;
}
15
Berik

UIScrollviewでも同じ問題が発生しました。この問題はcontentSizeを設定しないことが原因でした。 contentSizeをアイテムの数に設定すると、この問題は解決しました。

self.headerScrollView.mainScrollview.contentSize = CGSizeMake(320 * self.sortedMaterial.count, 0);
2
Antoine

ここに私のために働いたものがあります:
storyViewのscrollViewのサイズインスペクターで、コンテンツインセット調整動作を「なし」に設定します。

enter image description here

1
Eden

問題が発生しましたが、特定の場合-サイズを調整しません-次を使用しました:

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

したがって、サイズを変更する必要がない場合、これは迅速で簡単なソリューションです。

0

UIKitがプッシュアニメーション中にscrollViewのcontentOffsetを設定するという同様の問題が発生していました。

IOS 10とiOS 11をサポートしていたためかもしれませんが、これらのソリューションはどれも役に立ちませんでした。

Scrollviewをウィンドウから削除した後、UIKitがオフセットを変更しないようにscrollviewをサブクラス化することで、問題を修正できました。

/// 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
            }
        }
    }
}
0
Slimebaron

ScrollViewはDetailViewControllerのルートビューですか?はいの場合は、scrollViewをプレーンUIViewでラップして、後者をDetailViewControllerのルートビューにします。 UIViewsにはcontentOffsetプロパティがないため、Navigation Controller(Navigation Barなどによる)によるコンテンツオフセット調整の影響を受けません。

0
octy