为什么以下代码无法将活动指标定位到其超级视图的中心:
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给出的链接上找到了它,所以我接受了他/她的回答。
答案 0 :(得分:19)
以下四个Swift 5 / iOS 12代码示例显示了如何使用自动布局将UIActivityIndicatorView
置于UIView
UIViewController
内。
所有样品都会产生相同的结果,但根据您的需要和口味,您可以选择其中一种。
如果UIActivityIndicatorView
的超级视图不是self.view
,则只需将每个self.view
来电替换为您自己的(未打包的)superview
。
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)
*/
}
}
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
]
}
}
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)
}
}
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)
*/
}
}
答案 1 :(得分:6)
因为你并没有说明每一方的差距必须相同,所以它正在满足它的要求。试试这个:
[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];
哪个好看:)
答案 2 :(得分: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。
答案 3 :(得分:0)
我将活动指示器置于其超级视图中,方法是在Interface Builder中将其添加到alpha为零(以及我的视图控制器类中的IBOutlet)。然后我添加了约束以使其在X和Y轴中居中。最后,我添加了宽度和高度约束来消除自动布局错误。
在我的视图控制器的startActivityIndicator方法中,我将活动指示器的alpha设置为1,并在其上调用startAnimating方法。在我的stopActivityIndicator方法中,我在其上调用stopAnimating方法并将活动指示器的alpha设置回零。