UIViewのサブビューを中央に配置する方法


128

私はUIView内側にUIViewmがありUIView、幅と高さのサイズを変更しなくても、内側が常に外側の中央に配置されるようにしたいと思います。

サイズ変更を設定せずに、支柱とスプリングが上/左/右/下になるように設定しました。しかし、それはまだ中心にありません。何か案が?


2
受け入れられた答えは間違っており、クラッシュします。ヘジャズィの答えは素晴らしい。
Fattie

回答:


209

Objective-C

yourSubView.center = CGPointMake(yourView.frame.size.width  / 2, 
                                 yourView.frame.size.height / 2);

迅速

yourSubView.center = CGPoint(x: yourView.frame.size.width  / 2,
                             y: yourView.frame.size.height / 2)

51
ビューにがある場合はが定義されてboundsいないためframe、ではなくを使用する必要frameがありtransformます。
omz 2012年

1
size使用されているだけなので、実際にはこの場合は違いはありません。
Peter DeWeese

1
これは問題ではありません。frameビューtransformに恒等変換ではないがある場合、プロパティ全体は未定義です。UIViewのframeプロパティに関するドキュメントをお読みください。
omz

6
残念ながら、この答えは実際には間違っています。Hejaの正しい答えを使用してください。
Fattie

@Fattieここで何が間違っているのですか?私はそれをビュー内のImageViewを中央に配置するために使用し、それが機能しています。
jreft56

284

あなたはこれを行うことができ、それは常に動作します:

child.center = [parent convertPoint:parent.center fromView:parent.superview];

Swiftの場合:

child.center = parent.convert(parent.center, from:parent.superview)

1
後で忘れないでください、child.frame = CGRectIntegral(child.frame);
Fattie

8
1つ:これは、親ビューの中心/位置を変更していない場合にのみ機能します。2番目:この方法を使用している場合、ポイントを変換する必要はありません(すでに正しい形式になっています)を使用しますchild.center = parent.center。「child.center = CGPointMake(parent.bounds.height / 2、parent.bounds.width / 2)」を使用します。これにより、親ビューの中心が何に設定されているかに関係なく、常にサブビューが中心になります。
古い名前

1
ビューがまだビュー階層に追加されていない場合(オブジェクトを初期化するときなど)にも役に立ちません
Victor Jalencas

1
@Hejazi迅速な回答も追加するとよいでしょう;)
Milad Faridnia

1
@そうめんいいえ、違いがあります。スーパービューの座標系で指定されている間UIView.boundsビュー自体に相対的です(したがってbounds.origin、最初はゼロです)。UIView.center
Hejazi 2018年

41

始める前に、原点がCGPointビューの左上隅であることを思い出してください。見解と親について理解することが重要です。

次の単純なコードを見てみましょう。ビューに黒い四角を追加するビューコントローラーです。

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        createDummyView()
        super.view.backgroundColor = UIColor.cyanColor();
    }

    func createDummyView(){
        var subView = UIView(frame: CGRect(x: 15, y: 50, width: 50 , height: 50));
        super.view.addSubview(subView);
        view.backgroundColor = UIColor.blackColor()
    }

}

これにより、このビューが作成されます。黒い長方形の原点と中心は、親と同じ座標に適合します

ここに画像の説明を入力してください

次に、subViewに別のSubSubViewを追加し、subSubviewにsubViewと同じ原点を与えますが、subSubViewをsubViewの子ビューにします

次のコードを追加します。

var subSubView = UIView();
subSubView.frame.origin = subView.frame.origin;
subSubView.frame.size = CGSizeMake(20, 20);
subSubView.backgroundColor = UIColor.purpleColor()
subView.addSubview(subSubView)

そしてこれが結果です:

ここに画像の説明を入力してください

この行のため:

subSubView.frame.origin = subView.frame.origin;

紫色の長方形の原点は親(黒い長方形)と同じであると期待していますが、その下にありますが、それはなぜですか?別のビューにビューを追加すると、subViewフレーム「world」が親のBOUND RECTANGLEになるため、メイン画面の原点がすべてのサブビューの座標(15、15)にあるビューがある場合、左上隅は(0,0)になります

これが、親のバインドされた四角形、つまりそのsubViewの「世界」によって常に親を参照する必要がある理由です。この行を次のように修正してみましょう。

subSubView.frame.origin = subView.bounds.origin;

魔法を見ると、subSubviewはその親の起点に正確に配置されています。

ここに画像の説明を入力してください

それで、「親ビューだけで私のビューを中央に配置したかったのですが、大したことは何ですか?」まあ、大したことではありません。次のようにして、フレームから取得した親の中心点を親の境界中心に「変換」するだけです。

subSubView.center = subView.convertPoint(subView.center, fromView: subSubView);

あなたは実際に彼に「親ビューセンターを取り、それをサブサブビューの世界に変換する」と言っています。

そして、あなたはこの結果を得るでしょう:

ここに画像の説明を入力してください


行 'subSubView.center = subView.convertPoint(subView.center、fromView:subSubView)'が配置される場所に?
タマライT

26

私は使うだろう:

self.childView.center = CGPointMake(CGRectGetMidX(self.parentView.bounds),
                                    CGRectGetMidY(self.parentView.bounds));

CGRectオプションを使用したい...

SWIFT 3:

self.childView.center = CGPoint(x: self.parentView.bounds.midX,
                                        y: self.parentView.bounds.midY);

19

1.自動レイアウトを有効にしている場合:

  • ヒント:ビューをautolayoutを使用して別のビューの中央に配置するには、少なくとも1つの親ビューを共有する2つのビューに同じコードを使用できます。

まず、子ビューの自動サイズ変更を無効にします

UIView *view1, *view2;
[childview setTranslatesAutoresizingMaskIntoConstraints:NO];
  1. UIView + AutolayoutまたはPurelayoutの場合

    [view1 autoAlignAxis:ALAxisHorizontal toSameAxisOfView:view2];
    [view1 autoAlignAxis:ALAxisVertical toSameAxisOfView:view2];
  2. UIKitレベルのautolayoutメソッドのみを使用している場合:

    [view1 addConstraints:({
        @[ [NSLayoutConstraint
           constraintWithItem:view1
           attribute:NSLayoutAttributeCenterX
           relatedBy:NSLayoutRelationEqual
           toItem:view2
           attribute:NSLayoutAttributeCenterX
           multiplier:1.f constant:0.f],
    
           [NSLayoutConstraint
            constraintWithItem:view1
            attribute:NSLayoutAttributeCenterY
            relatedBy:NSLayoutRelationEqual
            toItem:view2
            attribute:NSLayoutAttributeCenterY
            multiplier:1.f constant:0.f] ];
    })];

2.自動レイアウトなし:

私は好む:

UIView *parentView, *childView;
[childView setFrame:({
    CGRect frame = childView.frame;

    frame.origin.x = (parentView.frame.size.width - frame.size.width) / 2.0;
    frame.origin.y = (parentView.frame.size.height - frame.size.height) / 2.0;

    CGRectIntegral(frame);
})];

6
受け入れられた回答とは異なり、このソリューションはピクセル境界にきれいに整列し、特定の幅のビューのぼやけを防ぎます。
ブラッド・ラーソン

1
私が間違っていなければ、child.frame = CGRectIntegral(child.frame); エレガントな一種のキャッチオールです/ BLが説明する問題の解決策はどこでも使用できます。
Fattie

1
@JoeBlow:頭を上げてくれてありがとう。以前は丸めが好きでしたが、ブロックスタイルを使用するとよりエレガントになりますCGRectIntegral
Cemal Eker

フレームを設定するために使用する構文について説明してもらえますか?プロパティに割り当てられているのは、常に「閉鎖」の最後のステートメントですか?そして、Appleのドキュメントのどこにありますか?
ヨハネス

「UIKitレベルのautolayoutメソッドのみを使用している場合:」はエラーになります。
Jonny、2015

13

最も簡単な方法:

child.center = parent.center

つまり、これがどのように機能するかについての説明/説明を追加する必要があります。
Tushar 2016

このタイプの多くの答えを検索しましたが、この単純な答えでうまくいきました。ありがとう。
gbossa

9

ここに画像の説明を入力してください

この自動サイズ変更マスクを内部ビューに設定します。


1
自動レイアウトでは、自動サイズ設定ウィンドウはありません。
アレン、

自動サイズ変更を使用する場合は、@ Allenで自動レイアウトを無効にする必要があります。
Mayank Jain、2014

8

IOS9では、レイアウトアンカーAPIを使用できます。

コードは次のようになります。

childview.centerXAnchor.constraintEqualToAnchor(parentView.centerXAnchor).active = true
childview.centerYAnchor.constraintEqualToAnchor(parentView.centerYAnchor).active = true

このオーバーの利点CGPointMakeかはCGRect、これらの方法であなたが定数にビューの中心を設定しているが、この技術であなたは永遠に保持する二つのビュー、どんなに関係に設定されていることであるparentview変更を。

これを行う前に、必ず確認してください。

        self.view.addSubview(parentView)
        self.view.addSubView(chidview)

translatesAutoresizingMaskIntoConstraints各ビューのfalse に設定します。

これにより、クラッシュやオートレイアウトによる干渉を防ぐことができます。


8

使用できます

yourView.center = CGPointMake(CGRectGetMidX(superview.bounds), CGRectGetMidY(superview.bounds))

そしてSwift 3.0では

yourView.center = CGPoint(x: superview.bounds.midX, y: superview.bounds.midY)

1
2番目のコード例は、swift 4で完全に機能します。
iGhost

はい!最後に、ありがとうございました。そのmidX / midYのことを知りませんでした。パーフェクト。
デイブY

5

ビューとサブビューで同じ中心を使用するのが最も簡単な方法です。このようなことができます

UIView *innerView = ....;
innerView.view.center = self.view.center;
[self.view addSubView:innerView];

これにより、ビューのスーパービューに対してサブビューが中央に配置されます。上記のケースでは、原点が(0、0)にあるため、機能しています。
Abdurrahman Mubeen Ali

3

を使用したPureLayoutによる別のソリューションautoCenterInSuperview

// ...
UIView *innerView = [UIView newAutoLayoutView];
innerView.backgroundColor = [UIColor greenColor];
[innerView autoSetDimensionsToSize:CGSizeMake(100, 30)];

[outerview addSubview:innerView];

[innerView autoCenterInSuperview];

これは次のようになります。

PureLayoutを備えたセンター



1

私は使うだろう:

child.center = CGPointMake(parent.bounds.height / 2, parent.bounds.width / 2)

これはシンプルで短く、甘いです。上記の@Hejaziの回答を使用し、サブビューparent.center以外に設定されている場合は(0,0)、中央に配置されません。


0
func callAlertView() {

    UIView.animate(withDuration: 0, animations: {
        let H = self.view.frame.height * 0.4
        let W = self.view.frame.width * 0.9
        let X = self.view.bounds.midX - (W/2)
        let Y = self.view.bounds.midY - (H/2)
        self.alertView.frame = CGRect(x:X, y: Y, width: W, height: H)
        self.alertView.layer.borderWidth = 1
        self.alertView.layer.borderColor = UIColor.red.cgColor
        self.alertView.layer.cornerRadius = 16
        self.alertView.layer.masksToBounds = true
        self.view.addSubview(self.alertView)

    })


}// calculation works adjust H and W according to your requirement
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.