Autolayoutを使用してUIScrollviewに制約を設定するにはどうすればよいですか?


176

私は2日間かけて、混合レイアウトと純粋なオートレイアウトアプローチのさまざまなソリューションを試して、オートレイアウトの前の簡単なスクロールビュー設定を実現しましたが、これは公式になりました-私は愚かすぎます。私はこれをストーリーボードで主に設定しています(まあ、それはまさにそれがそうである方法です)。

だからここに助けを求める私の嘆願があります。

ビューツリー:

UIView
-UIView
-UIView
..-UIScrollview
...-UIButton
...-UIButton
...-UIButton

ボタンは水平にスクロールすることになっています(左から右、およびその逆)。誰かお願いできますか私は、この使用して、純粋な自動レイアウトを達成するための制約を設定する方法を知っています?

-

私は次のように混合アプローチを試しました:

UIView
- UIView
- UIView
..-UIScrollview
...-UIView (contentview)
....-UIButton
....-UIButton
....-UIButton

...との固定幅と高さの制約を設定contentviewするtranslatesAutoresizingMaskIntoConstraints Appleのテクニカルあたりなどの設定。ボタンとスクロールビューは、制約を使用して設定されます。これはスクロールビューのスクロールを取得します(そうです)残念ながら、スクロールが遠すぎます!私の知る限りでは、スクロール幅は、コンテンツビューの設定から何とか2倍になります??? !!! ???

純粋なオートレイアウトアプローチも試しましたcontentview。を除くすべてのビューはtranslatesAutoresizingMaskIntoConstraints=NOですself.view。ボタンには幅と高さの制約があり、スクロールビューの4つの端すべてに固定されています。何もスクロールしません。

だから私はそれを正しく機能させることができない理由に完全に困惑しています。どんな助けでも大歓迎です、そしてあなたが他の情報を必要とするならば、尋ねてください!

ソリューションを含む更新されたスクリーンショット -buttonZ制約:

ここに画像の説明を入力してください

EDIT @ Jamie Forrest したがって、解決策は最後のボタンの間違った末尾制約であることが判明しました。6441の代わりに、私が設定した値は負の-6441でした。トリッキーなのは、ストーリーボードで値を設定するときに、ピンツールバーに2つのオプションがあることです。

ここに画像の説明を入力してください

現在のキャンバス値は負(スクロールなし)で、下のオプションは正(スクロールをアクティブ化)です。これは私が愚かではないが、少なくとも半盲だと思います。私の弁護のために、XCodeが「正しくない」設定のエラーを表示しないことは、いくらか気になるのではないですか?

EDITED AGAIN 今はこれが面白い... -6441(なしスクロール)から6441の末尾に値を変更してスクロールを可能にしました。しかし、私の古くからの友人、「コンテンツサイズが多すぎます」が戻ってきたため、コンテンツサイズは本来の2倍になりました。正しいコンテンツスクロールを取得するための解決策は、末尾の制約をゼロに設定することでした。これはStoryboardで作業する場合は明らかではありませんが、@ Infinity Jamesのコードを見ると、本来あるべき状態です。


スクロールビューのコンテンツサイズはどこで計算/設定しますか?contentViewを使用して最初の試みを参照して、スクロールが長すぎると述べました。
Tim

2
私の知る限り、自動レイアウトのみを使用するようcontentSizeに設定することはできませんUIScrollView。そして、contentSizeスクロールできる量を定義するのはそれです。そのため、最終的にはどこかに手動で設定する必要があります。それ以外の場合は、レイアウト拘束を使用して、相互に関連するビューフレームを設定できます。
ギヨーム

@Jeff、コンテンツのサイズは固定されており、変更されることはありません。contentiviewの正しい高さと幅を手動で入力してストーリーボードのコンテンツサイズを設定し、高さと幅をストーリーボードの制約付きで固定しました。
user1459524 2013年

実行時にcontentSizeを出力し、入力した値と一致するかどうかを確認します。contentSizeはスクロールの発生量を決定するため、最初の試行の問題はcontentSizeで行うことです。
Tim

@ギヨーム、「純粋な自動レイアウト」アプローチは結局それほど純粋ではないのですか?しかし、どうすればcontentSizeを手動で設定できますか?上で述べたように、コンテンツビューの高さ/幅を(ストーリーボードの)固定値に設定しています。しかし、スクロールが長すぎます(2倍)。
user1459524 2013年

回答:


68

ここに貼り付けたため、制約の正確な値と設定を確認するのは難しいため、間違っているスクリーンショットを確認してもわかりません。

セットアップの何が問題であるかを説明する代わりに、説明したものと非常によく似たビュー階層と制約セットアップを備えた基本的なサンプルプロジェクトを作成しました。水平スクロールは、Appleがテクニカルノートで説明している「Pure AutoLayout」アプローチを使用するサンプルプロジェクトで期待どおりに機能します。

また、もともとAuto Layoutをで動作させるのに多くの問題がありましたUIScrollView。これを機能させるための鍵は、スクロールビュー内のすべての項目をまとめて、最終的にはスクロールビューのすべての側面にリンクする制約があり、AutoLayoutシステムがフレームよりも大きくなるスクロールビュー。コードでそれを実行しようとしていたようですが、おそらくそこに余分な制約があり、contentSizeが小さすぎます。

また、他の人が述べたように、AutoLayoutとUIScrollviewを使用すると、contentSizeを明示的に設定する必要がなくなります。AutoLayoutシステムは、制約に基づいてcontentSizeを計算します。

また、この電子ブックの章は、これがどのように機能するかを理解させるのに非常に役立つことがわかりました。このすべてがお役に立てば幸いです。


2
サンプルプロジェクトをありがとう!それは機能し、それを調べている間、最初は自分のプロジェクトとの違いを見つけることができませんでした!制約以外の設定を疑って、ビューをプロジェクトにコピーしましたが、引き続き機能しました。これにより、プロジェクトの最後のボタンの末尾の制約に負の値があることに気づきました。その前に、あなたのボタンには正の値があります!-を正に変更すると、スクロールが有効になります!ピンツールバーを表示すると、2つの選択肢があります。負の値である現在のキャンバス値を使用することと、正の値であるスクロールビュー(現在値を使用すること)です。
user1459524 2013年

ああ、そうです。負の値を指定すると、実際にはスクロールビューのcontentSizeが小さくなり、ボタンが終了する前にトレーリングエッジが終了する必要があるという事実と一致します。サンプルプロジェクトが役に立ちました。
ジェイミーフォレスト

それはたくさんした。私の更新された答えをチェックしてください。末尾の値は実際には0(ゼロ)のようです。
user1459524 2013年

6
コードの代わりにスクリーンショットを共有しなければならないのは悲しいことです。これは、より良いAPIを提供する代わりに、Appleが開発者にビルダーの使用を奨励しているからです。
ウラジミール・Slavík

4
完全に直感的ではありません。開発者は、XCodeの作成者の心に何が起こっているのかを把握するために、何時間も浪費する必要があります。
Josh

49

愚かなクラブへようこそ。私は創設者の一人です。:D

垂直スクロールの場合:私がそれを機能させる唯一の方法(iOS 8、Xcode 6、および純粋な自動レイアウト)は、スクロールビューにすべてのスーパービューに関連する次の制約を追加することでした。

  • 等幅
  • 等しい高さ
  • 中心Y位置合わせ
  • 中心X位置合わせ

私の構造:

  UIView
   - ScrollView
    - Subview
    - Subview
    - Subview
    - Subview
    - ...

これが最終結果です。

デモ

これはセットアップです:

セットアップ 全画面表示

そして、これがプロジェクトです。

うまくいけば、これにより、誰かが午前5時に寝ることから救われます。:D


助けてくれてありがとう!タイプ「サブビュー」のサブビューはどのようにして取得しましたか?私はXcode 6.2であなたのプロジェクトを見ています、そしてそれはそれらの小さな長方形を「サブビュー」と呼び、唯一の制約はそれが63pxの高さであるということです。
Andrew K

1
こんにちは!その「サブビュー」は実際にはUIVIewです。それは単なる名前です...ここに何でも入力できます。この画像を確認してください:cl.ly/image/291f1K2N0V3p制約トピックでは、サブビューには高さ制約だけではありません。これらのビューの制約リスト全体をここで確認してください:cl.ly/image/3l061i123j2i
backslash-f

1
それでもスクロールを機能させることができません。プロジェクトでサブビューのビューが「グレー表示」されていることに気付きました。調査したところ、「サイズクラス」を使用していることが原因と考えられます。これはスクロールにどのように影響しますか?これを使用せずにスクロールを機能させる方法はありますか?
Andrew K

また、どのようにしてスーパービューをデフォルトの長さよりもはるかに長くしましたか?「スクロールせずに見える範囲」(または画面外)に表示されるボタンを追加しようとしていますが、十分に大きくないため、スーパービューにドラッグアンドドロップできない場合は、それらをスーパービューに追加できません。
Andrew K

1
この愚かなレイアウトを検索して試してみた長い一日の後で、私はこの答えを見つけて、最初の試みで動作しました。 )
Bobby Stenly、

32

簡単な自己完結型の例

質問への投票数が多く、回答への投票数が少ないことから判断すると、人々はここで理解できる迅速な解決策を見つけていません。追加してみましょう。このプロジェクトは、完全にInterface Builderで実行される自己完結型の例です。あなたはそれを10分以内に処理できるはずです。次に、学習した概念を自分のプロジェクトに適用できます。

ここに画像の説明を入力してください

元の質問は、スクロールボタンについて尋ねています。ここではUIViewsを使用していますが、好きなように表示できます。ストーリーボードのスクリーンショットはこの形式の方がコンパクトなので、横スクロールも選択しました。ただし、垂直スクロールでも原理は同じです。

重要な概念

  • UIScrollView唯一のサブビューを使用する必要があります。これは、スクロールするすべてを保持するコンテンツビューとして機能する「UIView」です。
  • コンテンツビューとスクロールビューのが水平スクロールの高さが等しくなるようにします。(垂直スクロールの幅は等しい)
  • スクロール可能なすべてのコンテンツが設定された幅を持ち、すべての側面に固定されていることを確認してください。

新しいプロジェクトを始める

単一のビューアプリケーションにすることもできます。

ストーリーボード

この例では、水平スクロールビューを作成します。ビューコントローラーを選択し、サイズインスペクターで[フリーフォーム]を選択します。幅1,000と高さを作り300ます。これにより、ストーリーボードにスクロールするコンテンツを追加する余地ができます。

ここに画像の説明を入力してください

スクロールビューを追加する

a UIScrollViewを追加し、4つの側面すべてをビューコントローラのルートビューに固定します。

ここに画像の説明を入力してください

コンテンツビューを追加する

UIViewスクロールビューにサブビューとして追加します。これが鍵です。スクロールビューに多数のサブビューを追加しないでください。単一を追加するだけUIViewです。これは、スクロールする他のビューのコンテンツビューになります。コンテンツビューを4辺すべてのスクロールビューに固定します。

ここに画像の説明を入力してください

等しい高さ

次に、ドキュメントアウトラインでCommand、コンテンツビューとスクロールビューの親ビューの両方をクリックして、両方を選択します。次に、高さが等しくなるように設定します(Controlコンテンツビューからスクロールビューにドラッグします)。これも重要です。水平方向にスクロールしているため、スクロールビューのコンテンツビューでは、このように設定しない限り、スクロールビューの高さがわかりません。

ここに画像の説明を入力してください

注意:

  • コンテンツを垂直にスクロールさせる場合、コンテンツビューの幅をスクロールビューの親の幅と等しくなるように設定します。

コンテンツを追加

3つUIViewのを追加して、すべての制約を与えます。すべてに8ポイントのマージンを使用しました。

ここに画像の説明を入力してください

制約:

  • 緑色のビュー:上、左、下の端を固定します。幅を400にします。
  • 赤色のビュー:上、左、下の端を固定します。幅を300にします。
  • 紫色のビュー:4つのエッジすべてを固定します。残りのスペースが何であっても(この場合は268)幅を設定します。

幅の制約を設定することも重要です。そのため、スクロールビューは、コンテンツビューの幅を認識します。

完成した

それで全部です。これでプロジェクトを実行できます。この回答の上部にあるスクロール画像のように動作するはずです。

垂直スクロールの場合は、この例のすべての幅と高さの方向を入れ替えるだけです(テスト済みおよび動作中)。

さらなる研究


9

contentSizeは、UIScrollView内の制約を適用することによって暗黙的に設定されます。

たとえば、UIView内にUIScrollViewがある場合、次のようになります(ご存じのとおり)。

    UIView *containerView               = [[UIView alloc] init];
    UIScrollView *scrollView            = [[UIScrollView alloc] init];
    [containerView addSubview:scrollView];
    containerView.translatesAutoresizingMaskIntoConstraints = NO;
    scrollView.translatesAutoresizingMaskIntoConstraints    = NO;
    NSDictionary *viewsDictionary       = NSDictionaryOfVariableBindings(containerView, scrollView);

    [containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|"
                                                                          options:kNilOptions
                                                                          metrics:nil
                                                                            views:viewsDictionary]];
    [containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|"
                                                                          options:kNilOptions
                                                                          metrics:nil

これにより、scrollViewがcontainerViewのサイズを満たすように設定されます(containerViewは特定のサイズでなければなりません)。

次に、次のようにボタンを保持するのに十分な大きさに暗黙的に設定することで、UIScrollViewのcontentSizeを調整できます。

    UIButton *buttonA                   = [[UIButton alloc] init];
    UIButton *buttonB                   = [[UIButton alloc] init];
    UIButton *buttonC                   = [[UIButton alloc] init];
    [scrollView addSubview:buttonA];
    [scrollView addSubview:buttonB];
    [scrollView addSubview:buttonC];
    buttonA.translatesAutoresizingMaskIntoConstraints       = NO;
    buttonB.translatesAutoresizingMaskIntoConstraints       = NO;
    buttonC.translatesAutoresizingMaskIntoConstraints       = NO;

    viewsDictionary                     = NSDictionaryOfVariableBindings(scrollView, buttonA, buttonB, buttonC);

    [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[buttonA]-|"
                                                                       options:kNilOptions
                                                                       metrics:nil
                                                                         views:viewsDictionary]];
    [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[buttonA]-[buttonB]-[buttonC]-|"
                                                                       options:NSLayoutFormatAlignAllBaseline
                                                                       metrics:nil
                                                                         views:viewsDictionary]];

それで、containerViewとボタンではなく、scrollViewとボタンの間に制約を設定しますか?私があなたのコードと私が今のところストーリーボードを介して何をしているのかについて私がスポーツしている唯一の違いについてだと思います。
user1459524 2013年

2回目を読んだ後、コンテンツビューではなくコンテナビューを設定していることに気付きました。あなたのコードに基づいて、ストーリーボードに正確にすべてを再作成しましたが、スクロールしていません。質問をいくつかのスクリーンショットで編集します。
user1459524 2013年

1
したがって、ストーリーボードでコードを再作成する私の試みは100%正しくなかったことがわかりました。最後のボタンの末尾の値は正確にゼロでなければならず、H:|-[buttonA]-[buttonB]-[buttonC]-|を反映しています。ストーリーボードで作業しているとき(または、少なくとも私にとってはそうではなかった)はそれほど明白ではありませんが、今では事実は取るに足らないようです。私は自動レイアウトが大好きですが、それらの小さなことが
うまくいき

@ user1459524が言及したのは私にとって問題でした。下のビューはボタンで、下の制約はIBによって-32でした。私はそれを0に設定し、それをIBでBottom Spaceに更新しました:superview。それはうまくいくでしょう、そしてあなたがそれがうまくいく前向きである限り、それはそうです。IBのバグのようです。それが他の誰かを助けることを願っています。私はまた、すべてのビューを削除して再配線しました。これは、これらを配置しようとするときに役立ち、通常はそれほど長くはかかりません。
マイケル

8

UIScrollViewでAutoLayoutを使用することについて非常に多くの質問がありますが、UIScrollViewの内部ビューはコンテンツビューに対して制約を作成しますが、UIScrollView自体に対しては制約を作成しないことが重要です。テクニカルノートTN2154を参照してください。

UIScrollViewクラスは、境界の原点を変更することにより、コンテンツをスクロールします。これを自動レイアウトで機能させるために、スクロールビュー内の上部、左、下部、および右端がコンテンツビューの端を意味するようになりました。

次の図は、それを示しています。 ここに画像の説明を入力してください

トレーリングスペースが500ポイントであることがわかります。UIScrollViewに制約が加えられている場合、ビューは配置されず、フレームを更新する必要があります。ただし、警告もエラーもありません。すべての制約がコンテンツビューに対するものだからです。

UIScrollViewは、内部ビューの制約に従ってコンテンツビューのサイズを計算します。(例では、コンテンツサイズ:幅= 100(先行スペース)+ 200(ビューの幅)+ 500(トレーリングスペース)、高さ= 131(上部のスペース)+ 200(高さ)+ 269(下部のスペース))

UIScrollViewでビューの制約を追加する方法:

  1. コンテンツビュー内のビューの位置を画像化する。
  2. コンテンツビューの端に上、右、下、左の間隔を追加し、さらにこれらのビューの幅と高さも追加します。

そして、それはすべて行われます。

スクロールビューでオートレイアウトを処理する簡単な方法は、スクロールビュー内のすべてのサブビューを含むコンテナビューを追加することです。

結論:UIScrollViewでAutoLayoutを理解するための重要なポイントは、UIScrollView自体ではなく、コンテンツビューに対して制約を作成する内部ビューです。

添付のサンプルコード


5

次の解決策は、autolayoutあり、contentSizeなしのscrollViewで私のために機能しました

  1. scrollViewをviewControllerにドラッグアンドドロップし、必要なスペースをカバーするためにあらゆる制約を適用します。
  2. scrollView内にUIViewをドラッグアンドドロップし、scrollViewのスペース全体をカバーし、scrollView から上、左、右、下のスペースになるように制約を適用します
  3. スクロールの必要性に応じて、内部ビューの高さ(および水平スクロールが必要な場合は幅)を設定します。この部分は、必要に応じてコードから実行することもできます。
  4. クリティカル。ポイント(3)で高さをいくつかの大きな値に設定した後、ポイント(2)に戻って、上、左、右、下の値をゼロに戻すようにしてください。 (3)で高さを変更しました。

これで完了です。これで、このビューに任意の数のコントロールを追加し、互いに関連する制約を適用できます(これらはこのビューなしでは機能していないようです)。このビューを使用しない場合は、scrollViewに関連する(互いに関連しない)各コントロールに制約を適用する必要があります。


圧倒的なヒント..............

クリティカル。わかりやすくするために、UIScrollViewの1000、高さが100であるとします。(実際、通常、これらの値はもちろん、デバイスの幅などに応じて動的になります。ただし、今のところ、幅1000、高さ100とだけ言います。)水平スクロールしているとしましょう。したがって、UIScrollView内にUIViewを配置します。(これが「コンテンツビュー」です。)コンテンツビューの上部、下部、リーディング、トレーリングの4つの制約すべてをスクロールビューに設定します。それが間違っているように見えても、それらをすべてゼロにします。コンテンツのUIViewの高さを100に設定し、それを忘れてください。ここで、水平方向にスクロールしたいので、コンテンツビューの幅を、たとえば1225に設定します。

コンテンツビューの幅が、親スクロールビューの幅より225大きいことに注意してください。それは大丈夫です。実際、あなたはそれをしなければなりません。ご了承ください

... トレーリング幅を負の225に設定しないでください...

通常のように幅を「一致」させる必要があると考えるでしょ。しかし、それを行うと、まったく機能しません。

先頭と末尾の数値をZEROに設定する必要があります(幅が「大きい」場合でも)。

興味深いことに、実際に先頭/末尾の数値を任意の正の値(「50」と言ってみてください)に設定すると、バウンスのマージンが得られます。(見栄えがよくなります:試してみてください。)どちらかの端に負の値があると、「静かに壊れます」。

腹立たしいことに、多くの場合Xcode(とにかく7.3.1以降)、

これらの値を「役立つ」ように負の数に設定します!

それはあなたのためにそれらを自動的に集計しようとするので。もしそうなら、それは静かに壊れます。最初のインスタンスでは、4つの値すべてをゼロに設定します。また、コンテンツビューの幅を例の「1000」よりもはるかに広く設定します。


編集: 私は私の要件のほとんどのためにUIScrollViewの代わりにUITableViewを使用してしまいました。tableViewの方がはるかに柔軟で動的なようです。


これは実際にはここでの最良の答えです。ありがとう!
Fattie、2016年

4

私はあなたがで問題に遭遇していると思いますcontentSize。対処方法については、このブログ投稿をご覧くださいcontentSize「純粋な」オートレイアウトアプローチを使用する場合の。その要点は、制約がコンテンツサイズを暗黙的に定義することです。AutoLayoutを使用する場合は、明示的に設定しないでください。ブログ投稿の最後にサンプルプロジェクトを添付して、それがどのように機能するかを示します


3

技術ノートに見落としている可能性がある部分があります。スクロールビューの端に固定された制約を使用して、スクロールビューのコンテンツサイズを暗黙的に設定できます。

簡単な例を示します。1つのスクロールビューを持つ1つのビューを持つストーリーボードを作成します。スクロールビューの制約を設定して、配置したビューのサイズに合わせます。

そのスクロールビュー内に単一のビューを追加します。制約を使用してそのビューのサイズを明示的に設定します(サイズがスクロールビューよりも大きいことを確認してください)。

次に、内部ビューにさらに4つの制約を追加して、内部ビューの4つのエッジを親のスクロールビューにロックします。これらの4つの制約により、コンテンツのサイズが拡大され、内部ビューに対応します。

スクロールビューに追加する複数のビューがある場合、たとえば水平にレイアウトする場合、最初のサブビューの左側をスクロールビューの左側にロックし、サブビューを互いに水平にロックし、右側をスクロールビューの右側にある最後のサブビューの側。これらの制約により、スクロールビューのコンテンツサイズが拡張され、すべてのサブビューとその制約に対応します。


3

あなたの質問が「フォーカスがあるときにキーボードの邪魔にならないように垂直スクロールUIScrollViewにたくさんのUITextFieldを配置するにはどうすればよいですか」である場合、最良の答えは次のとおりです。

しないでください。

代わりに、静的セルを含むUITableViewControllerを使用してください。

このスクロールアウトオブザウェイの動作は無料で、ビューコントローラーがUINavigationController内に表示されている場合は、すべてのコンテンツインセットが機能します。


3

あなた
ViewControllerViewScrollView、このcontains 、ScrollViewcontains ContainerViewContainerViewcontains 2のようにレイアウトを整理する必要がありますLabels
ここに画像の説明を入力してください

次に、3つの手順に従ってScrollViewスクロールできるようにします

  1. 設定ScrollViewピンをに(トップ/右/下/左)ViewControllerView
    • 設定ContainerViewピンをに(トップ/右/下/左)ScrollView
    • セットHorizontally in Containerしていない設定Vertically in Container
    • Label1ピン( /右/左)をContainerView
    • Label1ピン(右/左/ )へContainerViewトップLabel1

ここに画像の説明を入力してください

ここはデモプロジェクトです

この助けを願っています


1

純粋な自動レイアウトのアプローチは美しく機能しますが、非自動レイアウトから移行する場合は、セットアップが非常に面倒です。私はこれを数回やったことがあり、いくつかの一般的なヒントがあります:

  • 小さなものから始めましょう:ストーリーボードビューを再作成することを意味する場合でも、いくつかの要素から始めてゆっくりとビューを構築し、いくつかの要素を追加した後にスクロールが機能することを確認してください。
  • すべてに対してtranslatesAutoresizingMaskIntoConstraintsをオフにします。これが常に私にとって制約の競合の原因でした。
  • UIScrollView制約を適切に設定します。スクロールビューがすべての側面で親ビューに接続されていることを確認してください。そうでない場合、スクロールビューはまったく展開されません。

1

しばらくしてこの問題に対処した後、ようやく解決策を見つけました。ユニバーサルクラスサイズのストーリーボード(600x600)を使用しています。scrollViewのサイズのUIView(contentView)を作成し、ScrollViewのトップ、ボトム、リーディング、トレーリングの制約を作成しました。次に、contentViewのサイズを手動で600x600にクリップしました。ストーリーボードはすべてのサイズを変更しようとするのをやめ、私は作業できましたが、実際のデバイスまたはシミュレーターではビューがひどく見えました。このクリッピングされたサイズの2つの拘束アウトレットを作成しました。

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *contentViewWidthConstraint; 
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *contentViewHeightConstraint;

次にviewDidLoadで

CGSize viewSize = self.view.frame.size;
self.contentViewWidthConstraint.constant = viewSize.width;
self.contentViewHeightConstraint.constant = viewSize.height;

よく働く。


1

AutoLayoutビューと埋め込みScrollviewを使用して、スクロールビューを表示画面の中央に配置する方法の解決策を見つけるために何日も費やしました。

私はAutolayoutだけでそれをやろうと何日も費やしました、そして近づきましたが十分に近づきませんでした。したがって、最終的には、viewDidLoadで、画面ごとに3行のコードも追加する必要がありました。

以下の解決策を参照してください:

  1. スクロールビューを作成し、それに好きなオブジェクトを入れます
  2. 自動レイアウトをオンにする
  3. 次に、ScrollViewを垂直方向と水平方向の中央に配置します。 中央スクロールビュー
  4. ビューを選択し、「不足している制約を追加」を選択します -これはそれからそれを行います
  5. その結果、多くの制約が生成されます。ビューに対して2つの新しいものが作成されました。「Horizスペーススクロールビューからビューへ」と「Vertスペーススクロールビューからビューへ」、またはその逆です。
  6. 「Horiz space scrollview to View」を削除して、ビューに3つの制約を残します。ビューにスクロールビューを入力するための2と、スクロールビューとビューの間に垂直スペースを設定するための1
  7. 次に、Vert制約をコードにリンクとクリックしてCtrlでヘッダーファイルにドラッグし、NSLayoutConstraint IBOutletを作成します(私はmine constraintVertVtoSVと呼びます)。
  8. 今度は.mファイルに移動し、viewDidLoadにこれらのコード行を追加します(正しい頂点の中央揃えを取得するためにパディング量を試してください)。

    if (IPAD)

    {self.constraintVertVtoSV.constant = 150.0; }

  9. これはすべてのデバイスで実行され、適切に中央に配置され、適切にスクロールするはずです。


1

私のように、サブビュー内で制約なしに静的コンテンツを使用する場合、次のようにできます:

override func viewDidLayoutSubviews() {
    scrollView.contentSize = CGSizeMake(320, 800)
}

1

iOS 8.4、Xcode 6.4で今日私が抱えている同様の問題

サブビューを含むcontentView(UIView)を含む、スクロールビューを含むビューがあります。

すべてがどこでも自動レイアウトです。スクロールビューのエッジは、制約付きで親ビューのエッジに固定されます。コンテンツビューの端は、制約付きでスクロールビューの端に固定されます。

本来、コンテンツビューは、スクロールビューの全幅としてサイズを設定することを拒否していました。幅を親スクロールビューに一致させるには、コンテンツビューに追加の制約を追加する必要がありました。または、contentView.centerX == scrollView.centerX制約を設定することもできます。これらのいずれかにより、エッジの固定に加えて、コンテンツビューが適切なサイズになりました。

// Either one of these additional constraints are required to get autolayout to correctly layout the contentView. Otherwise contentView size is its minimum required size
scrollView.addConstraint(NSLayoutConstraint(item: contentView, attribute: .CenterX, relatedBy: .Equal, toItem: scrollView, attribute: .CenterX, multiplier: 1.0, constant: 0))
scrollView.addConstraint(NSLayoutConstraint(item: contentView, attribute: NSLayoutAttribute.Width, relatedBy: .Equal, toItem: scrollView, attribute: .Width, multiplier: 1.0, constant: 0.0))

フォームの視覚的制約を使用して、コンテンツビューの端をスクロールビューに固定します。

let cvConstraints = ["H:|[contentView]|", "V:|[contentView]|"]

ルーチンを使用して配列を反復処理し、それらをscrollViewに追加します。


1

私も同様の問題に直面しました。私はすべての制約を設定し、なぜそれがまだいくつかのサブビューのサイズを変更するのか疑問に思っていました。私の解決策は、clipsToBoundsをYESに設定することでした。


1

迅速なあなたは、この作業溶液を使用することができます。

拘束

ScrollView:リーディング、トレーリング、トップ、ボトム=スーパービュー

ContentView:Leading、Trailing、Top、Bottom = ScrollView。高さはコンテンツに対して固定/相対的です。

幅の制約(contentView)をスクロールビューのスーパービューと同じに設定できますが、プログラムで制約を追加するため、ビルド時に削除と削除を選択します。これは、IBが警告を出さないようにするためです。

extension UIView {

    func setupContentViewForViewWithScroll(contentView vwContent : UIView) {
        //Set constraint for scrollview content
        let constraint = NSLayoutConstraint(item: vwContent, attribute: NSLayoutAttribute.Width, relatedBy: .Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: self.bounds.size.width)
        vwContent.addConstraint(constraint)
        self.layoutSubviews()
    }

}

そしてView ControllerでviewDidLayoutSubviews私はこのメソッドを呼び出すだけです:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    self.view.setupContentViewForViewWithScroll(contentView: vwContent)
}

0

私はこれが素人の解決策であり、Appleが文書で提案しているものではないことを知っていますが、それは私にとって2回動作し、異なるコンテンツで非常に迅速に設定できます:ストーリーボードビューコントローラーにUIViewを挿入します。UIViewで、テーブルビュー、動的、0プロトタイプセル、スタイルプレーンまたはグループ化を挿入します。テーブルビューにスクロールビューを挿入し、スクロールビューにコンテンツを挿入します。それで、カスタムView Controllerの設定はありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.