UIScrollViewで垂直スクロールを無効にする


84

IBには、スクロールビューの垂直スクロールのチェックを外すオプションがありますが、機能していないようです。

コード内でIBではなく水平方向にのみスクロールし、垂直方向にはスクロールしないようにスクロールビューを設定するにはどうすればよいですか?


回答:


121

contentSizeの高さをscrollViewの高さに設定してみてください。次に、垂直方向にスクロールするものがないため、垂直方向のスクロールを無効にする必要があります。

scrollView.contentSize = CGSizeMake(scrollView.contentSize.width,scrollView.frame.size.height);

この奇妙な問題のデバッグにかかる​​時間を大幅に節約できました。ありがとう!
jpm 2013

2
@fabbフレームがいつ変更されたかをどうやって知るのですか?
サム

137

iOS7以降:

最初:コンテンツサイズの幅は、スクロールビューの幅と同じである必要があります

2番目:initWithNibName内:

self.automaticallyAdjustsScrollViewInsets = NO;

それでおしまい。


素晴らしい解決策。チャームのように働いた。ViewControllerの残りのビューのサイズに影響しますか?(ボタン、ラベル..)つまり、私の場合、「自己」はUIViewControllerです
voghDev 2014

@voghDevいいえ、スクロールビューのサブビューには影響しません。
Mirko Brunner 2014

アメージングは​​、問題が発生していたビューコントローラのviewdidloadメソッドにこれを追加しました。
StackRunner 2015

NavigationControllerを使用していて、私のようにスクロールビューがnavigationBarのタイトルの後ろにある場合は、viewDidLoadメソッドで使用します。解決します。
EFE 2015

1
ストーリーボードの設定で、コードを1行も使わずに直接同じことを実現できます。スクロールビューコントローラーを選択し、属性インスペクターの[スクロールビューインセットの調整]のチェックを外すだけです。
Morpheus78 2016年

49

はい、pt2ph8の答えは正しいです、

ただし、なんらかの奇妙な理由でcontentSizeをUIScrollViewよりも大きくする必要がある場合は、UIScrollViewプロトコルメソッドを実装して垂直スクロールを無効にすることができます。

 -(void)scrollViewDidScroll:(UIScrollView *)aScrollView;

これをUIViewControllerに追加するだけです

float oldY; // here or better in .h interface

- (void)scrollViewDidScroll:(UIScrollView *)aScrollView
{
    [aScrollView setContentOffset: CGPointMake(aScrollView.contentOffset.x, oldY)];
    // or if you are sure you wanna it always on top:
    // [aScrollView setContentOffset: CGPointMake(aScrollView.contentOffset.x, 0)];
}

これは、ユーザーがUIScrollViewをスクロールするときに呼び出されるメソッドであり、そうすることで、コンテンツが常に同じになるように強制します。


6
神!float oldY;上記のコードを参照するように、.mファイルでoldY変数を宣言しないでください。これは、アプリケーションごとのCスタイルの変数シンボルであり、変数はコントローラークラスのインスタンスメンバーとして宣言する必要があります。
イタチ

21

次の方法を含めます

-(void)viewDidLayoutSubviews{
    self.automaticallyAdjustsScrollViewInsets = NO;
}

スクロールビューのコンテンツサイズの幅をスクロールビューの幅と同じに設定します。


1
これは、ストーリーボードでView Controllerを選択し、そこでプロパティの
チェックを外す

1
私はすべてのスクロールビューのためにそれを設定しているため、このようにしないでください...ウィッシュあなたがなど新しいScrollViewクラスを作成したO / W図上で1つのスクロールビューに固有の可能性
VISC

20

必要な方向を無効にするには、コンテンツサイズに0を渡す必要があります。

垂直スクロールを無効にするには

scrollView.contentSize = CGSizeMake(scrollView.contentSize.width,0);

水平スクロールを無効にするには

scrollView.contentSize = CGSizeMake(0,scrollView.contentSize.height);

1
これにより、ビューのcontentSizeが、設定した軸上で0になるように設定されます。ContentSizeはコンテンツのサイズを参照しているため、画面の高さを渡して、そのフレームを超える垂直スクロールを無効にします。正しいとマークされたソリューションは正しいです。
システム

これは私にとってうまくいきました。contentSizeの高さとして高さを設定しても、垂直方向にスクロールできます。
KoreanXcodeWorker 2016

1
これは私にはうまくいきませんでした。self.automaticallyAdjustsScrollViewInsets
StackRunner

これです!スクロールビューの高さに設定することは私にはうまく
いき

18

コンテンツサイズを更新して垂直スクロールを無効にしましたが、スクロールする機能は残っていました。次に、スクロールを完全に無効にするには、垂直方向のバウンスも無効にする必要があることがわかりました。

たぶん、この問題を抱えている人もいます。


あなたは私を救いました。私のcontentSizeとframeは同じで、何が悪いのか理解できませんでした。本当にありがとう!!
yuf 2012

2
あなたの答えは、私がstackoverflowが大好きな理由です!:-)聖なる煙...これは私を狂わせた!あなたが正しいです。バウンス効果です。バウンス効果が必要ですが、スクロールする必要がない場合は必要ないので、スクロールする必要があるかどうかに応じて、コードでその効果を無効/再度有効にすることを検討します。
Erik van der Neut 2015年

2
さて、実行時にUIScrollViewでバウンスを有効/無効にするのは非常に簡単です。私の場合、スクロールコンテンツの高さだけを気にし、これでうまくいきました。self.scrollView.bounces=(BOOL)(self.scrollView.contentSize.height> self.scrollView.frame.size.height);
Erik van der Neut 2015年

12
- (void)scrollViewDidScroll:(UIScrollView *)aScrollView
{
    [aScrollView setContentOffset: CGPointMake(aScrollView.contentOffset.x,0)];

}

あなたは確認したに違いありません UIScrollViewDelegate

aScrollView.delegate = self;

4

yを常に一番上に設定するだけです。UIScrollViewDelegateに準拠する必要があります

func scrollViewDidScroll(scrollView: UIScrollView) {
        scrollView.contentOffset.y = 0.0
}

これにより、スクロールの減速/加速効果が維持されます。


4

iOS 11では、安全な領域ではなく画面の境界に固執するスクロールビューを作成することに関心がある場合は、以下を追加することを忘れないでください。

if (@available(iOS 11.0, *)) {
    [self.scrollView setContentInsetAdjustmentBehavior:UIScrollViewContentInsetAdjustmentNever];
}

1
結局。何千回もありがとうございます!あなたは私の日を救った
ha100 2018

0

iOS11から、次のプロパティを使用できます

let frameLayoutGuide: UILayoutGuide

あなたがのために制約を設定した場合frameLayoutGuide.topAnchorframeLayoutGuide.bottomAnchorをいくつかの同じアンカーにサブビューあなたのscrollViewその後、垂直スクロールが無効になり、高さscrollViewは、そのサブビューの高さと同じになります。


0

最も明白な解決策は、サブクラスのy座標の変更を禁止することです。

override var contentOffset: CGPoint {
  get {
    return super.contentOffset
  }
  set {
    super.contentOffset = CGPoint(x: newValue.x, y: 0)
  }
}

これは、次のような状況で唯一適切なソリューションです。

  1. 許可されていないか、デリゲートを使用したくないだけです。
  2. コンテンツの高さがコンテナの高さよりも大きい

0

多くの答えには、contentOffset0に設定することが含まれます。scrollView内のビューを中央に配置したい場合がありました。これは私のために仕事をしました:

public func scrollViewDidScroll(_ scrollView: UIScrollView) {
    scrollView.contentOffset.y = -scrollView.contentInset.top
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.