62

UIScrollViewペン先に a を入れ、それを anプロパティviewにリンクしました。IBOutlet

今、私が自分のviewDidLoadメソッドでこれを行うと、に影響を与えないようですcontentSize:

self.sv.backgroundColor = [UIColor yellowColor]; // this works
CGSize size =  CGSizeMake(1000.0, 1000.0); 
[self.sv setContentSize:size]; // this does not

contentSizeがフレームと同じであるかのように動作します。どうしたの?AutoLayoutをオフにすると、これが機能し始めました。なんで?

4

15 に答える 15

85

私も同じ問題を抱えていました。の自動レイアウトUIScrollViewがめちゃくちゃです。

回避策:すべてUIScrollViewを別UIViewのに入れ、それUIViewをの唯一の子として入れUIScrollViewます。次に、自動レイアウトを使用できます。

終わり近くのものが台無しになっている場合(UIScrollViewスクロールする方向の終わり)、可能な限り低い優先順位を持つように最後の制約を変更します。

于 2012-10-11T18:44:08.700 に答える
71

scrollViewのcontentSizeを更新するためにviewWillLayoutSubviewsを試してみましたが、うまくいきました。

- (void)viewDidLayoutSubviews
{
  [self.bgScrollView setContentSize:CGSizeMake(320, self.view.frame.size.height* 1.5)];
}

アップルドキュメント

-(void)viewDidLayoutSubviews

ビューがサブビューをレイアウトしたばかりであることをビュー コントローラーに通知するために呼び出されます。

討論

ビューコントローラーのビューの境界が変更されると、ビューはそのサブビューの位置を調整し、システムはこのメソッドを呼び出します。ただし、このメソッドが呼び出されても、ビューのサブビューの個々のレイアウトが調整されたことを示すわけではありません。各サブビューは、独自のレイアウトを調整する責任があります。

ビューがサブビューをレイアウトした後、View Controller はこのメソッドをオーバーライドして変更を加えることができます。このメソッドのデフォルトの実装は何もしません。

于 2014-03-31T11:46:39.540 に答える
21

最も簡単でクリーンな方法は、contentSize を viewDidAppear に設定して、自動レイアウトの効果を無効にすることです。これには、ランダム ビューの追加は含まれません。ただし、実装が機能するためにロード順序に依存することは、最善のアイデアではない場合があります。

于 2013-03-05T01:01:31.867 に答える
16

このコードを使用します。ScrollView setContentSize は、メイン スレッドで async と呼ばれる必要があります。

迅速:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    DispatchQueue.main.async {
        var contentRect = CGRect.zero

        for view in self.scrollView.subviews {
           contentRect = contentRect.union(view.frame)
        }

        self.scrollView.contentSize = contentRect.size
    }
}

目標 C:

 - (void)viewDidLayoutSubviews {
     [super viewDidLayoutSubviews];

     dispatch_async(dispatch_get_main_queue(), ^ {
                        CGRect contentRect = CGRectZero;

                        for(UIView *view in scrollView.subviews)
                           contentRect = CGRectUnion(contentRect,view.frame);

                           scrollView.contentSize = contentRect.size;
                       });
}
于 2016-09-02T12:45:29.203 に答える
15

Interface Builder内のUIScrollViewsでAutoLayoutを使用する非常に簡単な方法:

ステップ 1:を作成するUIScrollView

ステップ 2: 次UIViewのように、スクロール ビューの子である を作成します。

-UIScrollView
---UIView
-----Your other content

(これを と呼びますcontentView)。

ステップ 3:サイズ インスペクターで、このビューの高さと幅 (たとえば 320x700) を指定します。

ステップ 4 (AutoLayout を使用):contentViewスーパービュー ( ) への明確な制約を作成しますUIScrollView。4 つのエッジ (上、前、後、下) を接続し、スクロールする幅と高さを定義します。

例: スクロール ビューが画面全体にまたがる場合、コンテンツ ビューの幅を [device width]、高さを 600 にすることができます。次に、コンテンツのサイズUIScrollViewを一致するように設定します。

また:

ステップ 4 (AutoLayout を使用しない): IB を使用して、これらの新しいコントロールの両方をビュー コントローラーに接続します (ctrl キーを押しながら各コントロールからビュー コントローラーの .h @implementation にドラッグします)。scrollViewそれぞれが と と呼ばれるとしましょうcontentView。次のようになります。

@interface YourViewController : UIViewController

@property (strong, nonatomic) IBOutlet UIScrollView *scrollView;
@property (strong, nonatomic) IBOutlet UIView *contentView;

@end

ステップ 5 (AutoLayout を使用しない場合):ビュー コントローラーの .h ファイルに、次のメソッドを追加 (実際にはオーバーライド) します。

-(void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    self.scrollView.contentSize = self.contentView.frame.size;
}
于 2014-05-12T04:26:19.937 に答える
14

ここには 2 つの問題があります。(1) viewDidLoad は早すぎます。レイアウトが完了するまで待つ必要があります。(2) nib からの scrollview で autolayout を使用する場合は、制約を使用してサイズを完全に記述する必要がありますcontentSize(そして、contentSizein コードをまったく設定しません)。コードで設定したい場合は、スクロールビューのサブビューの制約がcontentSize. 後者をやりたいようですね。そのためには、スクロールビューの唯一の最上位サブビューとして機能する UIView が必要です。コードでは、autolayout を使用しないように設定し、それを有効にしautoresizingMaskて他の外部制約を削除する必要があります。その方法の例を次に示します。

https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/ch20p573scrollViewAutoLayout/ch20p573scrollViewAutoLayout/ViewController.m

ただし、次の例にも注意してください。これは、 の代わりに制約を完全に使用する方法を示していますcontentSize

于 2012-11-25T15:31:55.507 に答える
3

contentSize を設定することviewDidAppearは重要です。

しかし、3.5 インチの画面と 4 インチの画面で機能するもののバリエーションもありました。4 インチの画面は機能しましたが、古いものは機能しません。両方とも iOS 7 です。奇妙な表現は控えめです。

于 2013-12-13T20:53:34.183 に答える
1

制約に基づいて自動レイアウトを機能させることができませんでした。私のビューはすでにサブクラスの UIScrollView だったので、setContentView: をオーバーライドし、自動レイアウトの高さがゼロの setContentSize: メッセージを無視することで解決しました。

@interface MyView : UIScrollView {}
@end

@implementation MyView
- (void)setContentSize:(CGSize)aSize {
    if (aSize.height > 0)
        [super setContentSize:aSize];
}
@end
于 2014-01-18T17:48:09.617 に答える
1

uiscrollview と uiview を機能させる方法について、次の素晴らしいチュートリアルを段階的に見るまで、プログラムで uiscrollview をセットアップしていました: https://www.youtube.com/watch?v=PgeNPRBrB18

ビデオを見た後、Interface Builder が好きになると確信しています。

投票する

于 2014-08-27T22:15:54.860 に答える
1

ラベルの動的な高さがビューの高さを超えるとスクロールしません。

上記で正しいとマークされたyufの回答が行ったことを実行しました(スクロールビューにコンテンツビューを追加し、コンテンツビューからスクロールビューまでの先頭、末尾、上下、および等しい幅の制約を設定しました)が、それでも私のビューは内部コントロールの高さがスクロールビューの高さを超えたときにスクロールしない。

ここに画像の説明を入力

コンテンツ ビュー内には、画像とその下に 3 つのラベルがあります。各ラベルは、その中のテキストの量に応じて独自の高さを調整します (これを実現するために、ワードラップと numberoflines = 0 に設定されています)。

私が抱えていた問題は、スクロール ビュー/メイン ビューの高さを超えたときに、コンテンツ ビューの高さがラベルの動的な高さに合わせて調整されないことでした。

これを修正するには、下のラベルと contentview の間にBottom Space to Container制約を設定し、値を 40 に設定する必要があることを伝えました (下部に適切な余白を与えるために任意に選択しました)。これは、私の contentview がその高さを調整して、最後のラベルの下部とそれ自体の間にスペースがあり、完全にスクロールすることを意味します!

わーい!

于 2015-11-10T01:22:45.987 に答える
0

AutoLayoutaの を設定する本当に簡単な方法を使用している場合はcontentSize、次のUIScrollViewようなものを追加するだけです。

CGFloat contentWidth = YOUR_CONTENT_WIDTH;

NSLayoutConstraint *constraintWidth = 
 [NSLayoutConstraint constraintWithItem:self.scrollView 
                              attribute:NSLayoutAttributeTrailing 
                              relatedBy:NSLayoutRelationEqual 
                                 toItem:self.scrollView 
                              attribute:NSLayoutAttributeLeading 
                             multiplier:1 
                               constant:contentWidth];

[self.scrollView addConstraint:constraintWidth];
于 2014-03-27T18:44:51.677 に答える