web-dev-qa-db-ja.com

プログラムで自動レイアウトを使用して、アクティビティインジケーターをスーパービューの中央に配置するにはどうすればよいですか?

アクティビティインジケーターをスーパービューの中央に配置するために次のコードが機能しない理由:

UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc]
       initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];

[self.mysuperview addSubview:activityIndicator];
[activityIndicator addConstraints:[NSLayoutConstraint 
                   constraintsWithVisualFormat:@"|-(>=20)-[view(==100)]-(>=20)-|"
                   options:NSLayoutFormatAlignAllCenterX | NSLayoutFormatAlignAllCenterY
                   metrics:nil
                   views:@{@"view" : self.mysuperview}]];

アクティビティインジケーターは左上隅のどこかに配置されており、中央ではありません。

==================更新:見つかった解決策:インジケーターを作成した後、自動サイズ変更の制約をオフにしてから、指定されたすべてのソリューションをオフにする必要があります。

 [activityIndicator setTranslatesAutoresizingMaskIntoConstraints:NO];

@Vigneshからのリンクで見つけたので、彼/彼女の答えを受け入れます。

19
zyxel

あなたはこれを試すことができます、

 UIView *superview = self.mysuperview;
NSDictionary *variables = NSDictionaryOfVariableBindings(activityIndicator, superview);
NSArray *constraints =
[NSLayoutConstraint constraintsWithVisualFormat:@"V:[superview]-(<=1)-[activityIndicator]"
                                        options: NSLayoutFormatAlignAllCenterX
                                        metrics:nil
                                          views:variables];
[self.view addConstraints:constraints];

constraints =
[NSLayoutConstraint constraintsWithVisualFormat:@"H:[superview]-(<=1)-[activityIndicator]"
                                        options: NSLayoutFormatAlignAllCenterY
                                        metrics:nil
                                          views:variables];
[self.view addConstraints:constraints];

ここ から取得。

2
Vignesh

次の4つのSwift 5/iOS 12コードサンプルは、UIActivityIndicatorViewUIView内でUIViewController自動レイアウト

すべてのサンプルで同じ結果が得られますが、ニーズや好みに応じて、どちらかを選択できます。

UIActivityIndicatorViewのスーパービューがself.viewでない場合は、各self.view呼び出しを独自の(ラップされていない)superviewに置き換えるだけです。


1. NSLayoutConstraintイニシャライザスタイル

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let indicatorView = UIActivityIndicatorView(style: .gray)
        indicatorView.isHidden = false
        indicatorView.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(indicatorView)

        // Auto layout
        let horizontalConstraint = NSLayoutConstraint(item: indicatorView,
                                                      attribute: .centerX,
                                                      relatedBy: .equal,
                                                      toItem: self.view,
                                                      attribute: .centerX,
                                                      multiplier: 1,
                                                      constant: 0)
        let verticalConstraint = NSLayoutConstraint(item: indicatorView,
                                                    attribute: .centerY,
                                                    relatedBy: .equal,
                                                    toItem: self.view,
                                                    attribute: .centerY,
                                                    multiplier: 1,
                                                    constant: 0)
        NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint])
        /*
         // You can replace NSLayoutConstraint activate(_:) call with the following lines:
         self.view.addConstraint(horizontalConstraint)
         self.view.addConstraint(verticalConstraint)
         */
    }

}

2. UIViewAutoresizingスタイル

SpringsとStrutsは、実行時に対応する自動レイアウト制約に変換されます。

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let indicatorView = UIActivityIndicatorView(style: .gray)
        indicatorView.isHidden = false
        indicatorView.translatesAutoresizingMaskIntoConstraints = true // default is true
        self.view.addSubview(indicatorView)

        // Springs and struts
        indicatorView.center = CGPoint(x: self.view.bounds.midX, y: self.view.bounds.midY)
        indicatorView.autoresizingMask = [
            .flexibleLeftMargin,
            .flexibleRightMargin,
            .flexibleTopMargin,
            .flexibleBottomMargin
        ]
    }

}

3.ビジュアルフォーマット言語スタイル

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let indicatorView = UIActivityIndicatorView(style: .gray)
        indicatorView.isHidden = false
        indicatorView.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(indicatorView)

        // Auto layout
        let views = ["superview": self.view!, "indicatorView": indicatorView]
        let horizontalConstraints = NSLayoutConstraint
            .constraints(withVisualFormat: "H:[superview]-(<=0)-[indicatorView]",
                         options: .alignAllCenterY,
                         metrics: nil,
                         views: views)
        let verticalConstraints = NSLayoutConstraint
            .constraints(withVisualFormat: "V:[superview]-(<=0)-[indicatorView]",
                         options: .alignAllCenterX,
                         metrics: nil,
                         views: views)
        self.view.addConstraints(horizontalConstraints)
        self.view.addConstraints(verticalConstraints)
    }

}

4. NSLayoutAnchorスタイル(iOS 9が必要)

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let indicatorView = UIActivityIndicatorView(style: .gray)
        indicatorView.isHidden = false
        indicatorView.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(indicatorView)

        // Auto layout
        let horizontalConstraint = indicatorView
            .centerXAnchor.constraint(equalTo: self.view.centerXAnchor)
        let verticalConstraint = indicatorView
            .centerYAnchor.constraint(equalTo: self.view.centerYAnchor)
        NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint])
        /*
         // You can replace NSLayoutConstraint activate(_:) call with the following lines:
         self.view.addConstraint(horizontalConstraint)
         self.view.addConstraint(verticalConstraint)
         */
    }

}
19
Imanou Petit

両側のギャップが同じである必要があると言っているわけではないので、コーナーにいることで要件を満たしています。代わりにこれを試してください:

[self.superview addConstraint:[NSLayoutConstraint constraintWithItem:activityIndicator
               attribute:NSLayoutAttributeCenterX 
               relatedBy:NSLayoutRelationEqual 
                  toItem:self.superview 
               attribute:NSLayoutAttributeCenterX 
              multiplier:1.0 
                constant:0.0]];

そして、垂直方向に中央に配置するには、これも行います。

[self.superview addConstraint:[NSLayoutConstraint constraintWithItem:activityIndicator
               attribute:NSLayoutAttributeCenterY 
               relatedBy:NSLayoutRelationEqual 
                  toItem:self.superview 
               attribute:NSLayoutAttributeCenterY 
              multiplier:1.0 
                constant:0.0]];

または、FLKAutoLayoutプロジェクトを使用して、これらすべてを単純化することを強くお勧めします。

https://github.com/dkduck/FLKAutoLayout

次に、次のことができます。

[activityIndicator alignCenterXWithView:self.superview predicate:nil];
[activityIndicator alignCenterYWithView:self.superview predicate:nil];

いいですね:)

6
tarmes

アクティビティインジケーターを、アルファがゼロのInterface Builder(およびビューコントローラークラスのIBOutlet)に追加することで、スーパービューの中央に配置しました。次に、X軸とY軸の中央に配置するための制約を追加しました。最後に、自動レイアウトエラーを消すために、幅と高さの制約を追加しました。

ビューコントローラのstartActivityIndi​​catorメソッドで、アクティビティインジケータのアルファを1に設定し、そのメソッドでstartAnimatingメソッドを呼び出します。 stopActivityIndi​​catorメソッドで、stopAnimatingメソッドを呼び出し、アクティビティインジケーターのアルファをゼロに戻します。

0
Carl Smith