2013-07-21 9 views
5

私はUIScrollViewにUIViewを追加し、いくつかの余白を除いて、それが水平なスペースを埋めるように制約します。私の視覚的な制約は、次のようになります。それは行として表示されますので、私は高いビュー1つのピクセルを行ったUIViewがUIScrollViewのオートレイアウト制約に従わない

@"|-16-[theLineView]-16-|" 

、および2つのテキストラベルの間に置か:しかし

@"V:[someOtherStuff]-[aTextLabel]-[theLineView]-[anotherLabel]" 

、私が発見していますラインの幅は、ラベルの上/下の最長ラベルの幅まで広がっているだけです。

これはなぜでしょうか?私はここでは、このhttp://developer.apple.com/library/ios/#technotes/tn2154/_index.html

enter image description here

コード

を読んだ

P.Sは、iPadのシムでこの問題を示すテストプロジェクトからのビューコントローラコードの全体です。

- (void)viewDidLoad 

{[スーパーのviewDidLoad]。

self.scrollView = [[UIScrollView alloc] init]; 
self.scrollView.translatesAutoresizingMaskIntoConstraints = NO; 
self.scrollView.backgroundColor = [UIColor greenColor]; 
[self.view addSubview:self.scrollView]; 
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[scrollView]|" 
                   options:0 
                   metrics:0 
                    views:@{@"scrollView":self.scrollView}]]; 
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|" 
                    options:0 
                    metrics:0 
                    views:@{@"scrollView":self.scrollView}]]; 

self.line1 = [[UIView alloc] init]; 
self.line2 = [[UIView alloc] init]; 
self.label1 = [[UILabel alloc] init]; 
self.label2 = [[UILabel alloc] init]; 
self.label3 = [[UILabel alloc] init]; 

for (UILabel *label in @[self.label1, self.label2, self.label3]) 
{ 
    label.text = @"I am a label and I am long enough that I can be multiline on an iphone but single on ipad"; 
} 

for (UIView *view in @[self.line1, self.line2, self.label1, self.label2, self.label3]) 
{ 
    view.translatesAutoresizingMaskIntoConstraints = NO; 
    view.backgroundColor = [UIColor redColor]; 
    [self.scrollView addSubview:view]; 
} 

//horizontal layout - all views/labels should fill the horizontal space expect for margin 
for (UIView *view in @[self.line1, self.line2, self.label1, self.label2, self.label3]) 
{ 
    NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|-16-[view]-16-|" 
                    options:0 
                    metrics:0 
                    views:@{@"view":view}]; 
    [self.scrollView addConstraints:constraints]; 
} 

//vertical layout - stack em up 
[self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[lab1]-[line1(==1)]-[lab2]-[line2(==1)]-[lab3]-|" 
                    options:0 
                    metrics:0 
                    views:@{@"lab1":self.label1, @"line1":self.line1, @"lab2":self.label2, @"line2":self.line2, @"lab3":self.label3}]]; 

}

+0

あなたの1px UIViewに他の制約がありますか? – Yazid

+0

[view]は[theLineView]と同じビューですか? optionsパラメータにアライメントオプションを設定していますか? – rdelmar

+0

optionsパラメータに他の制約や何もありません。テストプロジェクトで再現できるかどうかを確認します。はい、これらのビューは同じで、スニペットを修正しました。 –

答えて

6

UIScrollViewのは、自動的に内部のビューに合うように縮小します。あなたは絶対にどこかに幅を設定する必要があります。

推奨戦術:

  1. 完全に制約(末尾の、主要な、上、下)を使用して、親ビュー内のscrollviewをfixiate。
  2. UIScrollView内にUIViewを作成し、必要なものをすべて内部に配置します。
  3. UIViewがコンテンツビューとして機能するように制約を設定します(これは、すべての要素を含めるのに十分な大きさを意味します)。内在的なコンテンツサイズ、縮みにくさ、および制約の多い要素の連鎖を使用します。結果のレイアウトは明確でユニークでなければなりません(これは、すべての制約を外部に取り除く場合、レイアウトは引き続き機能することを意味します)。
  4. UIViewの境界線をスーパービュー(UIScrollViewではなくUIScrollViewの実際のコンテンツビュー)に接続します。

インターフェイスビルダでこれを行う場合(可能です)、そのシーンで何かをタッチするたびに制約を再確認する必要があります。タッチでは、「変更」だけでなく「選択」を意味します。

+0

私のために働かなかった、どのように私はスクロールビューの全体の幅を埋めるためにUIViewを設定するには? – AndiDog

+0

私が言ったように、contentViewはscrollViewが縮小するので、常にscrollViewをいっぱいにします。あなたは内側に幅を設定しなければなりません。あなたの例では、 "| -16- [view] -16- |" "| - 16- [view(288)] - 16 - |"あなたに良い結果を与えるはずです。 –

+3

これは機能します。ナンバー4は、シンプルで魔法の数字を避ける(回転などをサポートするという意味)ので、私の意見ではより良いアプローチです。 –

2

あなたのユースケースでもうまくいくはずの解決策が見つかりました。 hereを参照してください。

2

Patric Sc​​henkeの答えの4番目に拡大しています。 scrollViewのコンテンツサイズが流動的であるため、内部のビューをそのエッジに固定するだけでは、ビューの幅を決定することができません。あなたの左側のピンは動作しますが、どちらも動作しません。次のレベルのコンテナに基づいてビューの幅を計算することが最善の方法です。self.scrollViewがコンテナ(これはcontainerViewと呼んでいます)に固定されている限り、このコード行は必要なものを達成します。水平方向の制約のためにあなたのforループに次の行を追加します

// Pin view's width to match the scrollView container's width 
// -32 constant offset for margins 
[containerView addConstraint: 
    [NSLayoutConstraint constraintWithItem:view 
           attribute:NSLayoutAttributeWidth 
           relatedBy:NSLayoutRelationEqual 
            toItem:containerView 
           attribute:NSLayoutAttributeWidth 
           multiplier:1.0f 
           constant:-32]]; 
0

私は(私は、このソリューションの脆さの度合いをテストしていない)、これを達成するための簡単な制約ベースの方法を見つけた:

[email protected]"H:|-16-[view]-16-|"... // (your original constraint) 

[self.scrollView addConstraint: 
    [NSLayoutConstraint constraintWithItem:view 
           attribute:NSLayoutAttributeCenterX 
           relatedBy:NSLayoutRelationEqual 
            toItem:self.scrollView 
           attribute:NSLayoutAttributeCenterX 
           multiplier:1.0f 
           constant:0.0f]]; 

これは、ビューの反対側の端まですべてviewを伸ばします。これは、おそらく水平方向にスクロールするコンテンツに対しては理想的ではありませんが、垂直方向に動作する必要があります。

これは1年以上経っていることを認識していますが、patric.schenkeの回答(これは優れており、より堅牢です)よりも単純なスクロールの使用例です。

関連する問題