How to position activity indicator to the center of its superview using Auto Layout programmatically?

后端 未结 4 1788
终归单人心
终归单人心 2021-02-12 12:18

Why the following code does not work for positioning activity indicator to the center of its superview:

UIActivityIndicatorView *activityIndicator = [[UIActivity         


        
相关标签:
4条回答
  • 2021-02-12 12:50

    You can try this,

     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];
    

    Taken from here.

    0 讨论(0)
  • 2021-02-12 13:05

    It's meeting it's requirements by being in the corner, since you're not stating that the gaps on each side have to be the same. Try this instead:

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

    And to center vertically do this too:

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

    Alternatively, I highly recommend using the FLKAutoLayout project to simplify all this:

    https://github.com/dkduck/FLKAutoLayout

    Then you can do:

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

    Which is nice :)

    0 讨论(0)
  • 2021-02-12 13:08

    The four following Swift 5 / iOS 12 code samples show how to center a UIActivityIndicatorView inside the UIView of a UIViewController with Auto layout.

    All samples produce the same result but, according to your needs and tastes, you may choose one or the other.

    If your UIActivityIndicatorView's superview is not self.view, you simply have to replace each self.view call with your own (unwrapped) superview.


    1. NSLayoutConstraint initializer style

    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 style

    Springs and Struts will be translated into corresponding auto layout constraints at runtime.

    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. Visual Format Language style

    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 style (requires 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)
             */
        }
    
    }
    
    0 讨论(0)
  • 2021-02-12 13:11

    I centered my activity indicator in its superview by adding it in Interface Builder with an alpha of zero (and an IBOutlet for it in my view controller class). Then I added constraints to center it in the X and Y axes. Finally, I added width and height constraints to it to silence an autolayout error.

    In my view controller's startActivityIndicator method, I set the alpha of the activity indicator to one and call the startAnimating method on it. In my stopActivityIndicator method, I call the stopAnimating method on it and set the alpha of the activity indicator back to zero.

    0 讨论(0)
提交回复
热议问题