11

自動レイアウト環境でUIScrollViewがどのように機能するかを理解しようとしています。これまで、Appleのドキュメント、Stack Overflowの調査、Googleの調査を読み、MattNeubergの実例を調べてみました。

Apple6.1のドキュメントには次のように書かれています。

UIScrollViewオブジェクト(または単にスクロールビュー)の中心的な概念は、コンテンツビュー上で原点を調整できるビューであるということです。コンテンツをフレームにクリップします。フレームは、通常(必ずしもそうとは限りませんが)、アプリケーションのメインウィンドウのフレームと一致します。スクロールビューは指の動きを追跡し、それに応じて原点を調整します。スクロールビューの「スルー」でコンテンツを表示しているビューは、コンテンツビューのオフセットに固定されている新しい原点に基づいて、その部分を描画します。スクロールビュー自体は、垂直および水平のスクロールインジケーターを表示する以外は描画しません。スクロールビューは、スクロールを停止するタイミングを認識できるように、コンテンツビューのサイズを認識している必要があります。デフォルトでは、スクロールがコンテンツの境界を超えると「バウンス」します。

これに基づいて、制約をどのように設定する必要があるかを見ていきましょう。

議論を容易にするために、一般的なケースとして3つのビューがあるとします。デフォルトのメインビューコントローラビュー(A)、そのサブビューはUIScrollview(B)であり、UIScrollviewにはUIView(C)である単一のサブビューがあります。 )。(C)の高さを1000ユニットにしたいとします。

そこで、Interface Builderに入り、ストーリーボードでView Controllerを選択し、属性インスペクタータブでサイズをフリーフォームに変更します。ビュー(A)、(B)、および(C)の場合、サイズインスペクタータブで高さを1000に変更します。

(A)とメインウィンドウの間の制約

制約を設定する時間です。ドキュメントには、「(Scrollview)はコンテンツをフレームにクリップします。これは通常(...)アプリケーションのメインウィンドウのフレームと一致します」と明記されています。この例では、(A)はアプリケーションのメインウィンドウと一致し、これに制約は必要ありません。

(A)と(B)の間の制約

これで、(B)が(A)と正確に一致することについてドキュメントが明確になったので、それらの間に4つの制約、先頭のスペース、末尾のスペース、上部のスペース、下部のスペースを設定して、すべてを定数0で監視します。

(B)と(C)の間の制約

ここでのドキュメントはそれほど単純ではありません。(B)の原点は(C)よりも調整可能であるため、(B)は(C)よりも確実に小さくする必要があります。スクロールは上下にしか移動しないことがわかっているので、(B)と(C)の間の左右のエッジをゼロに制限できます。常に中央に配置して、中央を追加します。 xアライメント。それらの間に3つの制約を追加します。先頭のスペースと末尾のスペースを定数0のスーパービューに追加し、中央をxに配置します。ビューを配置するには、上下に何かが必要です。正直なところ、ドキュメントに基づいてこれらの制約をどのように設定する必要があるのか​​わかりません。MattNeubergの例を模倣したものに基づく定数0でスーパービューする上部スペースと、デフォルトで生成される定数でスーパービューする下部スペースを作成しました。この下部スペースからスーパービューへの制約は(明らかに)特別であり、今後は「specialConstraint」と呼ばれます。

だから何?!この段落は、(B)は(C)よりも確実に小さいはずだと言って始め、制約を設定してまったく同じサイズにすることで終わりました。質問1-これはなぜですか?

(C)自体に対する制約

(B)が何かをスクロールできるように、(C)は(B)よりも大きくなければならず、(C)はそれ自体の制約に基づいてそのサイズを決定する必要があることがわかっています。簡単に、1つの制約、高さ=1000を設定します。

specialConstraint

次に、View ControllerでspecialConstraintのアウトレットを作成し、viewDidLoadメソッドでself.specialConstraint.constant=0を設定します。つまり、コンテンツビューの下部は、スクロールビューの下部に正確に固定する必要があります。これにより、下にスクロールすることはできなくなります。しかし、これはMattNeubergの例では機能します。質問2-これはなぜですか?

Scrollviewがスクロールするときに実際に何が起こっているのか

論理的には、スクロールビューのフレームを固定し、コンテンツビューの原点(またはコンテンツオフセット)をスクロールに合わせて移動すると、コンテンツにウィンドウのようにスクロールビューが表示されると思います。紙をスライドさせて壁の穴から紙を見るのと似ています。

しかし、私の読書に基づくと、scrollviewのフレームは、固定ページ上の虫眼鏡のように、実際に移動しています。

質問3-スクロールビューがスクロールしたときに何が起こっているのか、どのオブジェクトのフレームの原点が実際に変化しているのか、なぜこのように行われるのかを誰かに説明してもらえますか?

質問4-平易な英語で(A)、(B)、(C)の間に制約を設定する方法を誰かが説明できますか?

4

3 に答える 3

0

この謎の問題を解決するための基本的なトリックは..スクロールビュー内に別のビューを埋め込み、以下のような制約を設定します

UIView --> UIScrollView -->ContentView

実行時にサブビューを contentView に追加し続けると、uiscrollview コンテンツのサイズが自動的に増加します

   self.ContentView = [[UIView alloc] initWithFrame:CGRectZero];
    self.ContentView.translatesAutoresizingMaskIntoConstraints = NO;
    self.scrollview = [[UIScrollView alloc] initWithFrame:CGRectZero];
    self.scrollview.translatesAutoresizingMaskIntoConstraints = NO;
    [self.scrollview sizeToFit];

    [self.scrollview addSubview:self.ContentView];
    [self.view addSubview:self.scrollview];

    NSMutableDictionary *views = [[NSMutableDictionary alloc] init];

    [views setValue:self.ContentView forKey:@"ContentView"];
    [views setValue:self.scrollview forKey:@"scrollview"];
    [views setValue:self.view forKey:@"mainView"];

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[scrollview]-0-|"
                                                                             options:0
                                                                             metrics:nil
                                                                               views:views]];

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[scrollview]-0-|"
                                                                             options:0
                                                                             metrics:nil
                                                                               views:views]];

    [self.scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[ContentView]|"
                                                                             options:0
                                                                             metrics:nil
                                                                               views:views]];

    [self.scrollview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[ContentView]|"
                                                                             options:0
                                                                             metrics:nil
                                                                               views:views]];

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[ContentView(==mainView)]"
                                                                      options:0
                                                                      metrics:nil
                                                                        views:views]];

    self.view.contentMode = UIViewContentModeRedraw;

    [self.view setNeedsUpdateConstraints];
于 2015-07-31T12:55:57.543 に答える
0

私はそれを行う方法の例をたくさん見つけましたが、実行時にコンテンサイズを設定する方法を説明するものはありませんでした. だからボタンで。

実際には、スクロールビューのコンテンツとスクロールビューの間に関係があることに要約されます。

これで、ストーリーボードだけでコードなしでスクロールビューのスクロールとサイズ変更を行うことができます。あなただけがそれを正しくしなければなりません。

(実行時に) ボタンで圧縮を調整するには、コンテンツの制約を調整する必要があります。

これは理解するのが難しいです。コードを github http://goo.gl/qrXANpに置きました。ここでビデオを見つけることができます... https://www.youtube.com/watch?v=4oCWxHLBQ-A

于 2014-02-20T18:03:05.687 に答える