Как позиционировать индикатор активности в центр его просмотра с помощью автоматической компоновки?
Почему следующий код не работает для позиционирования индикатора активности в центре его супервизора:
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, поэтому я принимаю его/ее ответ.
Ответы
Ответ 1
Вы можете попробовать это,
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
Четыре следующих примера кода Swift 3 показывают, как центрировать UIActivityIndicatorView
внутри UIView
UIViewController
с помощью автоматического макета.
Все образцы производят одинаковый результат, но, в соответствии с вашими потребностями и вкусами, вы можете выбрать один или другой.
Если ваш просмотр UIActivityIndicatorView
не является self.view
, вам просто нужно заменить каждый вызов self.view
на свой собственный (развернутый) superview
.
1. NSLayoutConstraint
стиль
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let indicatorView = UIActivityIndicatorView(activityIndicatorStyle: .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
стиль
Спрингс и Struts будут переведены на соответствующие ограничения макета во время выполнения.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let indicatorView = UIActivityIndicatorView(activityIndicatorStyle: .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(activityIndicatorStyle: .gray)
indicatorView.isHidden = false
indicatorView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(indicatorView)
// Auto layout
let views: [String: Any] = ["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 (требуется iOS 9)
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let indicatorView = UIActivityIndicatorView(activityIndicatorStyle: .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)
*/
}
}
Ответ 3
Он отвечает требованиям, находясь в углу, так как вы не заявляете, что пробелы на каждой стороне должны быть одинаковыми. Вместо этого попробуйте:
[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];
Что приятно:)
Ответ 4
Я сосредоточил свой индикатор активности в своем супервизии, добавив его в Interface Builder с альфой нулевого значения (и IBOutlet для него в классе контроллера вида). Затем я добавил ограничения, чтобы центрировать его в осях X и Y. Наконец, я добавил ограничения ширины и высоты, чтобы отключить ошибку автоопределения.
На мой взгляд, метод startActivityIndicator для контроллера, я установил альфа индикатора активности в один и вывел на него метод startAnimating. В моем методе stopActivityIndicator я вызываю на нем метод stopAnimating и снова устанавливаю альфу индикатора активности.