web-dev-qa-db-ja.com

Interface BuilderでUIScrollViewを使用するにはどうすればよいですか?

過去にプログラムで操作することでUIScrollViewを正常に使用してきましたが、Interface Builderで排他的に設定することで動作させるのに問題があります。

IPhoneアプリにシンプルな「about」ページがあります。 UITextView、いくつかのアイコン、他のアプリへのリンクがあります。これらのすべてのビューをUIScrollViewに追加し、合計サイズが480を超えるように配置しました。アプリを起動すると、スクロールビューには画面に収まるコンテンツのみが表示され、何もスクロールしません。

IBを介してこれを完全に行うことは可能ですか、またはコードを使用してcontentSizeを操作する必要がありますか?

95
George Armhold

UIScrollViewのcontentSizeプロパティを設定するのを忘れていました。奇妙なことに、Interface Builderからこれを行うことはできません。このスクロールビューを管理するView Controllerから実行する必要があります。

130
Stefan Arentz

Boby_Wanの答えは私に考えさせられ、Interface BuilderからUIScrollViewのcontentSizeを構成するための次のソリューションを見つけました。

  1. ストーリーボードシーンでUIScrollViewを選択します
  2. Identityインスペクターに移動し、新しいユーザー定義ランタイム属性を作成します(+ボタンをクリックします)
  3. 属性Key PathcontentSizeに変更します
  4. 属性TypeSizeに変更します
  5. Valueを{望ましいコンテンツの幅望ましいコンテンツの高さ}に設定します

たとえば、値を{320、920}に設定すると、ユーザーはiPhoneの余分な画面全体を下にスクロールできます。

(xcode 4.3.3を使用していますが、プロジェクトのiOS Deployment Targetは5.1です)

最初にこれを行ったとき、次のエラーを受け取りました。

不正な構成:
4.3より前のXcodeバージョンのサイズタイプのユーザー定義ランタイム属性
MainStoryboard.storyboard

このエラーが発生した場合も簡単に修正できます。Project NavigatorでStoryboardを選択し、Fileインスペクターを表示しますInterface Builder Documentセクションを検索/展開すると、Developmentのドロップダウンがあります。これがXcode 4.3に設定されていることを確認してください

113
Herr Grumps

Autolayout(iOS6 +)を使用すると、contentSizeの設定を回避できます。代わりに、次の制約を設定します。

  1. Scrollviewの上部を最上部の子の上部に固定します。
  2. そして、一番下の子の底に底を固定します。
25
Danyal Aytekin

Interface Builderのみを使用してこれを実行し、Identity Inspector(3番目のインスペクタータブ)に移動して、新しいユーザー定義ランタイム属性を追加します。

  • キーパス:contentSize
  • タイプ:サイズ
  • 値:{幅、高さ}
18
Anton Banchev

ストーリーボードを離れずにUIScrollViewスクロールを作成する方法があります:

  1. ストーリーボードでUIScrollViewを選択し、サイズインスペクターに移動して、Bottom値(または変更する必要があるその他の値)を- Content Insetsコンテンツ領域の高さまでのセクション。
  2. 次に、IDインスペクターに移動し、新しいユーザー定義のランタイム属性を作成し(+ボタンをクリックして)、contentSizeという名前を付けます。 TypeまたはValueを入力しても問題ありません(デフォルト値のままでもかまいません)。

これによりUIScrollViewが適切に動作しますが、なぜ2番目のステップが必要なのかわかりません(偶然見つけました)。 :(

14
RoberRM

私が過去に使用した1つのアプローチは、スクロールビューをインターフェイスビルダーのビューを含むからドラッグして、実際のサイズをcontentSizeにしたいものに設定することです。

インターフェイスビルダーについて本質的に明らかではないことは、ペン先に保存されているが、ペン先が主に使用するメインビューの一部ではない、関連付けられていないビューを持つことができることです。

スクロールビューを表示するビューで、プレースホルダーとして使用するシンプルなUIViewを配置します。 (これは単に、場所を視覚的に設計できるようにするためです。ビュー全体を使用している場合は、この手順をスキップして、この回答の最後にある2番目のコードスニペットを使用できます)。

その後、スクロールビューにコントロールを追加し、視覚的に思いどおりにレイアウトすることができます。 View Controller内にプレースホルダーとスクロールビューの両方のプロパティを指定して、実行時にアクセスできるようにします。

実行時、in-(void)viewDidLoad

scrollView.contentSize = scrollView.frame.size;
scrollView.frame = placeholder.frame;
[placeholder.superview addSubView:scrollView];
[placeholder removeFromSuperview];

または(プレースホルダーを使用しなかった場合):

CGRect f = self.view.frame;
scrollView.contentSize = f.size;
f.Origin.x = 0;
f.Origin.y = 0;
scrollView.frame = f;
[self.view addSubView:scrollView];

最後に、インターフェイスビルダーでスクロールビューを「失う」場合(デザイングリッドから消えるように閉じることが可能です)、パニックにならないでください。デザイングリッドの左側にあるオブジェクトリストでそれをクリックするだけです。

4
unsynchronized

上記の答えの多くは、誤解を招くか、時代遅れです。 2017年(おそらくずっと以前)の時点で、インターフェイスビルダーdoesは、自動的にサイズ変更されたコンテンツでのスクロールビューをサポートします。秘Theは、XCodeがscrollviewとその中のコンテンツとの間の制約に特別な非標準の意味を与えることです。これらの「内側の」制約は、not実際にコンテンツのサイズに影響します。

これは、例えばスクロールビューをメインビューの下部にゼロマージンで固定し、スクロールビューのコンテンツをスクロールビューの下部にゼロマージンで固定しますが、コンテンツは実際にはこれによってストレッチされません。代わりに、コンテンツのサイズは自己決定型になり(以下で説明します)、これはスクロールビュー内のスクロール可能な領域のサイズにもなります。

このように考えてください-スクロールビューへの制約のバインドには非対称性があります。スクロールビューから「外部」(親)ワールドへの制約は、通常どおりスクロールビューのサイズと位置を決定します。ただし、スクロールビューの「内側」の制約は、スクロールビューのスクロール可能な領域のサイズと位置を、コンテンツにバインドすることで実際に設定しています。

制約を設定しようとすると、XCodeは常に現在の間隔を示唆し、内向きと外向きの制約を競合するように意図的に変更することは決してないため、これは完全に非自明です。ただし、上記の意味があり、スクロールビューのレイアウトを制御し、スクロール可能なコンテンツ領域のサイズを制御します。

私は偶然これに出くわし、それがどのように動作するように見えるかを見て、それを完全に説明し、Apple docs source for this:

https://spin.atomicobject.com/2014/03/05/uiscrollview-autolayout-ios/

コンテンツの自己決定サイズに関する最後の重要な情報の1つ:通常、コンテンツのサイズをたとえば親ビューの幅ですが、この場合、親はスクロールビューであり、上記のように-制約はコンテンツのサイズに影響しません。ここでの答えは、ビュー階層内で直接隣接していないアイテムにアイテムを制限できることを思い出してください。無駄にスクロールビューを取得する代わりに、コンテンツビューの幅をメインビューの幅に設定できます。

4
Pat Niemeyer

自動レイアウトを使用するXcode 4.5では、サイズインスペクターにコンテンツインセットセクションがありません。そのため、ユーザー定義のランタイム属性の下に追加する必要がありましたが、正常に機能しました。

「ユーザー定義のランタイム属性」に追加するのはkeyPath == contentInsetで、タイプは「Rect」(Rectと同じ入力を持つUIEdgeInsets)で、{top、left}、{bottom、right}として定義されます。 contentSizeは、scrollviewウィンドウの領域のみを定義します。 contentInsetは、スクロール可能な領域を定義します。

これが同じ状況の誰かに役立つことを願っています。

4
Robert Wasmann

スクロールビューのautoLayoutを削除するだけです。コードは次のように簡単です:

scrollviewName.contentSize = CGSizeMake(0, 650);

.hファイルでibouletプロパティを作成してから、.mファイルで合成します。スクロールが有効になっていることを確認してください。

2
Aldrin Equila

Interface Builderを介してUIScrollViewを設定することは直感的ではありません。これを設定するためのチェックリストは次のとおりです。

  1. UIViewControllerのXIBファイルを選択します。インターフェースビルダーの「Identity Inspector」で、UIViewをクラスタイプUIScrollViewに変更します

  2. [ファイルインスペクター]で、[自動レイアウト]のチェックを外します

  3. [属性インスペクター]で、サイズを[フリーフォーム]に変更します。その後、スクロールビューを手動で拡大するか、[サイズインスペクター]でカスタムの幅と高さを指定できます。

  4. 「Identity Inspector」で、タイプ「Size」の「contentSize」と呼ばれる新しいユーザー定義ランタイム属性を追加し、{320、1000}のような値に変更します。これをプログラムで設定することはもうできないため、スクロールビューの内容がウィンドウよりも大きいことをスクロールビューに知らせるために、この手順が必要です。

2
Free Mason

Interface BuilderでView Controllerのプロパティアイコンをクリックすると、シミュレートされたメトリックで「フリーフォーム」サイズに設定し、メインビューのサイズを目的のコンテンツサイズに変更できます。

このようにして、ScrollViewのコンテンツを1つの大きなビューのように作成できます。シミュレートされたメトリックにすぎないため、View Controllerはロード時にウィンドウの境界に合わせてサイズ変更されます。

2
oliland

StoryLayoutでは、Autolayoutsを使用してUIScrollViewを使用できます。基本的に必要なものは次のとおりです。

  1. UIScrollViewを追加
  2. すべての制約を追加します(上、左、右、下の端からのインセットなど)
  3. 「コンテナ」UIViewをUIScrollViewに追加します
  4. 一方向のスクロール(垂直など)のみが必要な場合:高さを明示的に設定し(たとえば600)、幅をUIScrollViewの幅にリンクします。
  5. 双方向スクロールが必要な場合は、幅と高さの両方を設定するだけです。

storyboard setup

1

はい、 st3fan が正しい場合、UIScrollViewのcontentSizeプロパティを設定する必要があります。ただし、この目的のために自動レイアウトをオフにしないでください。 UIScrollViewのcontentSizeは、コードなしでIBのみの自動レイアウトで簡単に設定できます。

UIScrollViewのautolayout contentSizeが直接設定されていない場合、UIScrollViewのすべてのサブビューの制約に基づいて計算されることを理解することが重要です。そして必要なのは、両方向のサブビューに適切な制約を提供することです。

例えば。サブビューが1つしかない場合、その高さとスペースを上下からスーパービュー(つまり、この場合はscrollView)に設定できますcontentSize.heightは合計として計算されます

Vertical Space (aSubview.top to Superview.top) + aSubview.height + Vertical Space (aSubview.top to Superview.top)

contentSize.widthは、水平方向の制約から同様に計算されます。

ContentSizeを適切に計算するための制約が少なすぎる場合、View Controller Sceneアイテムの近くに小さな赤いボタンが表示され、レイアウトのあいまいさが通知されます。

多くのサブビューがある場合、それは制約の「連鎖」である可能性があります: Danyal Aytekin answerのように、最上部から最上部までのサブビュー、サブビュー間の高さおよびスペース、最下部から最下部までのサブビュー。

しかし、実際には、ほとんどの場合、必要なサイズの空のビューを追加し、スペースをscrollViewの上下左右に0に設定する方が便利です。このビューを「コンテンツビュー」として使用できます。つまり、他のすべてのサブビューを配置するか、すでに多くのサブビューがあり、それらを移動してレイアウトを再設定したくない場合は、この補助ビューを既存のサブビューに追加して非表示にすることができます。

ScrollViewをスクロール可能にするには、計算されたcontentSizeをscrollViewのサイズより大きくする必要があります。

1
Vladimir

ストーリーボードで完全に画面よりも大きいコンテンツでScrollViewを設計するためのソリューションを次に示します(ほぼ完全に、1行のコードも追加する必要があります)。

https://stackoverflow.com/a/19476991/1869369

0
Ronny Webers

もっと便利な方法を見つけました。

1:スクロールビューのサイズをスケーリングして、その中にすべてのUIを含めます。

2:スクロールビューのiboutletを追加します。

3:viewDidLoadで、スクロールビューのframe.sizeを保存します。
(例:_scrollSize = _scrollView.frame.size;)

4:viewWillAppearで、以前に保存したCGSizeでcontentSizeを設定します。
(例:_scrollView.contentSize = _scrollSize;)

5:完了〜

0
Agas
  1. UIViewControllerを追加
  2. UIViewControllerの「Attribute Inspector-> Simulated Metrics」でサイズを自由に設定
  3. UIViewControllerの「サイズインスペクター->ビューコントローラー」で高さ800を設定
  4. UIViewControllerにUIScrollViewを追加します
  5. すべての制約をUIScrollView(上、左、右、下)に追加し、配置を追加X =中央
  6. UIScrollViewにUIViewを追加
  7. すべての制約をUIView(上、左、右、下)に追加し、配置X =中央を追加します。はい、#3のUIScrollViewと同じですが、UIViewの場合
  8. UIViewに高さの制約を追加します。たとえば780
  9. 走る

Storyboard

0
Alexander

新しいXcodeプロジェクトを作成する

Main.storyboardファイルに移動します

オブジェクトライブラリからScrollViewを選択します。

ScrollViewのフレームを設定します。

別のビューをスクロールビューに追加し、フレームをScrollViewと同じに保ちます。

高さと幅を動的に設定するには、次のようにします XIBの自動レイアウトを使用してUIScrollViewを構成

0
Dilraj Singh