web-dev-qa-db-ja.com

iOSのScrollViewには、yの位置または高さの制約が必要です

-ViewController
--View
---ScrollView (Top,Bottom,Leading,Trailing spaces to superview set to 0)
----ContentView (Top,Bottom,Leading,Trailing spaces to superview set to 0, Width equals with View (ViewController's child))
-----Label1
-----etc...

コンテンツビューに特定の高さ制限(1000など)を設定すると、ScrollViewは正常に機能しますが、1000の静的ContentViewを取得しましたが、これは目標ではありません。contentViewが動的コンテンツを取得したため、コンテンツの高さニーズ。

ContentViewの高さの制約を削除すると、Xcodeは次のように言います。

Missing Constraints:
ScrollView need constraints for: Y position or height

ScrollViewは実際には上下に固定されているため、XcodeがScrollViewの高さ制限を必要とする理由がわかりません...

ContentViewの高さをコンテンツに必要な高さにしたいときの正しい方法は?

42
Bioaim

自動レイアウトでScrollViewを使用する場合は、常に以下の手順に従ってください

  1. ScrollView制約:leadingSpace、topSpace、TrailingSpace、bottomSpaceをsuperViewに追加し、ドラッグを制御して制約を追加するときにaltキーを押して追加し、制約がマージンなしで設定されるようにします。

  2. スクロールビュー内にUIViewをコンテンツビューとして追加し、altボタンを押さずにその制約(leadingSpace、topSpace、trailingSpace、bottomSpace)をScrollViewに設定し、equalWidthをScrollViewに設定します。

  3. このコンテンツビュー内に追加するビューには、すべてのビューに垂直方向の制約が必要な上から下への制約が必要です。したがって、contentViewは、内部のコンテンツに基づいて自身に必要な高さを計算できます。

制約が正しく設定されている場合、scrollViewは内部のコンポーネントに基づいてコンテンツサイズを自動的に設定し、コンテンツサイズを手動で設定する必要はありません。また、scrollViewはコンテナビュー内のコンポーネントが内部に収まらない場合にのみスクロールしますそれ以外の場合はスクロールしません。とにかくスクロールさせたい場合は、ストーリーボードの垂直方向のバウンスプロパティをチェックして、バウンス効果を得る必要があります。

注:scrollView内のコンポーネントに制約を設定している間、制約を設定するまで制約の警告が表示されます。一番上のコンポーネントは一番下に、一番上のコンポーネントにはsuperViewに対する上部の制約(垂直方向の制約)があり、一番下のコンポーネントにはスーパービューに対する下部の空間制約があることを忘れないでください。これが満たされると、最終的にすべての警告が消えます。

ScrollViewの制約:

enter image description here

ContainerViewの制約:

enter image description here

131
Bharat Modi
  1. View Controllerを選択してください
  2. [スクロールビューのインセットを調整]のチェックを外します

enter image description here

2
alicanozkara

Bharat Modiの答えはほとんど問題を解決しますが、私(Xcode 8.3.2、iOS 10 SDK)もコンテンツビューの高さと幅をUIScrollViewの高さと幅に一致させる必要がありました。

これにより、コンテンツのサイズは表示領域のみに固定されますが、IBは満足のいくものになります。それから(私は思う)それはちょうどコンテンツサイズを正しく計算し、プログラムで設定するだけの問題です。動的コンテンツがある場合は実行時にしか実行できないため、とにかくやらなければならなかったでしょう。

ナビゲーションバーがある場合は、View Controllerの「スクロールビューインセットの調整」設定を微調整する必要があるかもしれません。

これは私が持っているものです:

UIScrollView in IB without warnings

公式の提案( https://developer.Apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithScrollViews.html )また、これを行う必要があることも述べないでください。

スクロールビュー、コンテンツビュー、固定幅と高さのダミービューだけを使用してコンテンツを模倣してこれを理解しようとしましたが、IBを満足させるものは何もありませんでした。

(申し訳ありませんが、元の回答のコメントとしてこれを掲載するのに十分な担当者がいません)。


更新:

実際に私がやったことは、IBでコンテンツビューを固定の高さに設定し、コードでその高さの制約のアウトレットを作成することです。次に、ビューがすべての動的コンテンツをロードした後、次のように高さの制約を更新します。

self.uiContentViewHeightConstraint.constant = mapViewBottomY + 15

そして、すべてが機能します。ここで重要なのは、スクロールビュー内にビューがある場合、そのビューがスクロールビューのコンテンツサイズを定義するということです。前に述べたように、コンテンツビューのサイズは、IBを満足させるために、ビルド時に完全に定義する必要があります。アウトレットからでも実行時に値を自由に操作できます。簡単で安全です。

IBでコンテンツビューを固定サイズにする利点の1つは、コンテンツサイズを固定したため、相対オフセットを使用してコンテンツビュー内のビューを通常どおり定義できるようになったことです。

1
denis.kim

それが動作します

-ViewController
--View
---ScrollView (Top,Bottom,Leading,Trailing spaces to superview set to 0)
----ContentView (Top,Leading,Trailing spaces to ScorllView set to 0 | Height to dynamic (1000))
-----Label1
-----etc...

ContentView、コンテンツの独自の計算についても同じことを行います

- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:YES];
[self adjustHeightOfTableview];
}

- (void)adjustHeightOfTableview
{
CGFloat height = tblMainMenu.contentSize.height;
CGFloat maxHeight = tblMainMenu.superview.frame.size.height - tblMainMenu.frame.Origin.y;

// if the height of the content is greater than the maxHeight of
// total space on the screen, limit the height to the size of the
// superview.

if (height > maxHeight)
    height = maxHeight;

// now set the height constraint accordingly
self.tableViewHeightConstraint.constant = height;
[UIView animateWithDuration:0.1 animations:^{
    [self.view setNeedsUpdateConstraints];
}];
}

編集1

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    NSString *OptName_length = @" Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam";
    NSDictionary *attributes = @{NSFontAttributeName: [UIFont systemFontOfSize:17.0]};
    CGRect rect = [OptName_length boundingRectWithSize:CGSizeMake(tableView.bounds.size.width-150.0, MAXFLOAT)
                                                  options:NSStringDrawingUsesLineFragmentOrigin
                                               attributes:attributes
                                                  context:nil];

    CGSize requiredSize = rect.size;
    return requiredSize.height +5.0f;
    }

Edit 2

サイトを確認してください、これはあなたを助けます... itableviewcell-dynamic-height-with-autolayout-conclusion

1
Jaleel Nazir

スクロールビュー内のコンテンツビュー内の一番下の要素のボトムスペース制約が0に設定され、コンテンツビュー内のすべての要素の高さが設定されていることを確認してください。

これにより、コンテンツビュー内の要素に応じてコンテンツビューのサイズが変更され、スクロールビュー/コンテンツビューの高さが固定されておらず、スクロールビューは携帯電話の画面サイズに合わせてサイズが変更されます。

1

Scrollviewのコンテンツビューでラベルの左上および右下のマージンの制約を設定し、UILableの行数を0に設定します。これにより、コンテンツのサイズに従ってコンテンツビューが拡張されます。

enter image description here

ちょっとしたトリック-UIScrollViewにUITextViewが含まれている場合

「ScrollViewにはyの位置または高さの制約が必要です」。または「UIScrollViewスクロール可能なコンテンツサイズのあいまいさ」

IBのUITextViewでデフォルトの「Scrolling Enabled」のチェックを外すだけです。魔法のように機能します:) enter image description here

0
Vitya Shurapov