如何使用自动布局以编程方式将活动指示器定位到其超级视图的中心?

问题描述 投票:19回答:4

为什么以下代码不能将活动指示器定位到其超级视图的中心:

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给出的链接上找到了它,所以我接受了他/她的回答。

ios autolayout uiactivityindicatorview
4个回答
2
投票

你可以试试这个,

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

取自here


19
投票

接下来的四个Swift 5 / iOS 12代码示例展示了如何将UIActivityIndicatorView置于UIView的自动布局中。

所有样品都会产生相同的结果,但根据您的需要和口味,您可以选择其中一种。

如果你的UIViewController的超级视图不是UIActivityIndicatorView,你只需用你自己的(未包装的)self.view替换每个self.view电话。


1. superview初始化风格

NSLayoutConstraint

2. 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) */ } } 风格

Springs和Struts将在运行时转换为相应的自动布局约束。

UIViewAutoresizing

3.视觉格式语言风格

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

}

4. 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) } } 风格(需要iOS 9)

NSLayoutAnchor

6
投票

因为你并没有说明每一方的差距必须相同,所以它在角落里满足了它的要求。试试这个:

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)
         */
    }

}

垂直居中也是这样做的:

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

或者,我强烈建议使用FLKAutoLayout项目来简化所有这些:

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

然后你可以这样做:

https://github.com/dkduck/FLKAutoLayout

哪个好:)


0
投票

我将活动指示器置于其超级视图中,方法是将它添加到Interface Builder中,其alpha值为零(以及我的视图控制器类中的IBOutlet)。然后我添加了约束以使其在X和Y轴中居中。最后,我添加了宽度和高度约束来消除自动布局错误。

在我的视图控制器的startActivityIndi​​cator方法中,我将活动指示器的alpha设置为1,并在其上调用startAnimating方法。在我的stopActivityIndi​​cator方法中,我在其上调用stopAnimating方法并将活动指示符的alpha设置回零。

© www.soinside.com 2019 - 2024. All rights reserved.