Why the following code does not work for positioning activity indicator to the center of its superview:
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}]];
Activity indicator is positioned somewhere at the top left corner, definitely not in the centre.
================== Update: FOUND SOLUTION: I have to turn off autoresizing constraints after creating indicator and then all solutions that where given work:
[activityIndicator setTranslatesAutoresizingMaskIntoConstraints:NO];
I found it on the link given by @Vignesh, so I accept his/her answer.
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
.
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)
*/
}
}
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
]
}
}
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
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)
*/
}
}
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 :)
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 .
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.