8

contentModeプロパティに関するUIViewの公式ドキュメントによると:

The content mode specifies how the cached bitmap of the view’s layer is adjusted when the view’s bounds change

この定義の内容は何によって定義されていますか? それはサブビューですか、それともビューの背景色を定義した場合などです。

UIViewContentModeCenter私の最初の推測では、少なくともビュー内のサブビューに適用する必要がありますが、たとえば、次のコード スニペットでは、タグを操作したときに期待した結果が得られません 。

 UIView* redView = [[UIView alloc] initWithFrame:CGRectMake(80, 80, 150, 200)];
 redView.contentMode = UIViewContentModeCenter;
 redView.backgroundColor = [UIColor redColor];

 UIView* greenView = [[UIView alloc] initWithFrame:redView.bounds];
 greenView.backgroundColor = [UIColor greenColor];
 [redView addSubview:greenView];

 redView.frame = CGRectInset(redView.frame, -5, -5);
 [self.view addSubview:redView];

greenView を含む redView をセットアップしました。また、redview のコンテンツ モードを次のように設定しましたUIViewContentModeCenter。親のフレームを変更したときに、書いたコードで greenView が中央に配置されないのはなぜですか? すべきことではないUIViewContentModeCenterか。

明確にしてくれてありがとう!

Ps:上記のコードはloadView、単純なビュー コントローラー テンプレート プロジェクトで簡単にテストできます。

4

2 に答える 2

10

ドキュメントから:

コンテンツ モードは、ビューの境界が変更されたときに、ビューのレイヤーのキャッシュされたビットマップがどのように調整されるかを指定します。

画像ビューの場合、これは画像について話しています。コンテンツを描画するビューの場合、これは描画されたコンテンツについて話しています。サブビューのレイアウトには影響しません。

サブビューにある自動サイズ変更マスクを確認する必要があります。コンテンツ モードは、ここではニシンです。自動サイズ変更マスクを使用して必要なレイアウトを実現できない場合は、layoutSubviews を実装し、サブビューの位置とフレームを手動で計算する必要があります。

jrturton の回答から: https://stackoverflow.com/a/14111480/1374512

于 2013-03-28T06:27:05.380 に答える
5

ここでコンテンツモード について最初に読んでください

あなたの例では、赤いビューのフレームを変更します。これにより、ビューでlayoutSubviewsが呼び出され、レイアウトの制約または自動サイズ変更マスクに従って緑色のビューが再配置されます。何も指定していません。したがって、緑色のビューのフレームは同じままです。

コンテンツモードは、サイズ変更時にビューのレイヤーを更新する方法を指定します。コンテンツモードに応じて、drawRectが呼び出されるかどうかが決まります。

次の例を使用して、さまざまなコンテンツモードの効果をテストできます。

このdrawRect実装を使用して円を描画するUIViewサブクラスを追加します。

- (void)drawRect:(CGRect)rect
{
    // Drawing code
    NSLog(@"drawRect %@", NSStringFromCGRect(rect));

    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextAddEllipseInRect(ctx, self.bounds);
    [[UIColor redColor] setFill];
    CGContextFillPath(ctx);
}

ビューコントローラで、サークルビューを作成して追加します。

CircleView* circleView = [[CircleView alloc] initWithFrame:CGRectMake(10, 10, 20, 20)];
circleView.contentMode = UIViewContentModeCenter; // <- try different modes here
[self.view addSubview:circleView];

次に、フレームをアニメートして、何が起こるかを見てみましょう。

dispatch_async(dispatch_get_main_queue(), ^{
    [UIView animateWithDuration:5 animations:^{
        circleView.frame = CGRectMake(10, 10, 100, 200);
    }];
});

CoreGraphicsに元のフレームで少なくとも1回はビューを描画させるために、これを非同期で実行しています。コンテンツモードを設定しないと、再描画せずにスケールアップするだけなので、円がぼやけてしまいます。UIViewContentModeCenterを使用すると、小さな円が中央に留まります。また、再描画は必要ありません。UIViewContentModeRedrawは、ビューに新しいフレームでビューを再度描画させます。実際、それはアニメーションが始まる前に起こります。

コンテンツモードは描画パフォーマンスに影響を与える可能性があることに注意してください。

于 2012-10-20T13:18:41.230 に答える