IOS - Позиционирование UIView в центре наблюдения с использованием Auto Layout программно
Как программно установить UIView в центр его просмотра с помощью Auto Layout?
UIButton* viewObj = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[viewObj setTranslatesAutoresizingMaskIntoConstraints:NO];
[viewObj setBackgroundColor:[UIColor greenColor]];
[self.view addSubview:viewObj];
NSLayoutConstraint* cn = [NSLayoutConstraint constraintWithItem:viewObj
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0];
[self.view addConstraint:cn];
cn = [NSLayoutConstraint constraintWithItem:viewObj
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0];
[self.view addConstraint:cn];
Этот код работает для меня для UIButton, но мне не удается заменить первую строку чем-то, что работает для UIView.
Я пробовал
UIView* viewObj = [UIView alloc] initWithFrame:CGRectZero];
но представление не отображается в симуляторе.
Любые предложения?
Спасибо!
Ответы
Ответ 1
Поскольку вы задали этот вопрос в контексте использования автоматического макета, здесь проблема заключается в том, что UIButton имеет собственный размер (передается через метод intrinsicContentSize), который предоставляет автоматическую компоновку информацию о ширине и высоте, но UIView обычно делает не. Поэтому вам нужно добавить дополнительные ограничения, связанные с шириной и высотой.
Если вы хотите, чтобы ваш UIView был установленным размером (скажем, 200x200), вы могли бы добавить следующие строки:
cn = [NSLayoutConstraint constraintWithItem:viewObj
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1
constant:200];
[viewObj addConstraint:cn];
cn = [NSLayoutConstraint constraintWithItem:viewObj
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1
constant:200];
[viewObj addConstraint: cn];
Обратите внимание, что аргумент toItem:
nil
, а второй атрибут NSLayoutAttributeNotAnAttribute
, потому что вы не указываете ширину и высоту относительно чего-либо еще. Если вы хотите, чтобы высота и ширина подвыбора были относительно надзора (скажем, 0,5), вы могли бы сделать это:
cn = [NSLayoutConstraint constraintWithItem:viewObj
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeHeight
multiplier:0.5
constant:0];
[self.view addConstraint:cn];
cn = [NSLayoutConstraint constraintWithItem:viewObj
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeWidth
multiplier:0.5
constant:0];
[self.view addConstraint: cn];
Ответ 2
UIButton
, UIImageView
, UIlabel
и UITextField
могут автоматически устанавливать свой размер в соответствии с их свойствами содержимого. Ширина и высота a UIImageView
задаются символом UIImage
, который может содержать. Размер a UIlabel
будет зависеть от его текста. Ширина и высота UIButton
определяются заголовком и изображением, которое у него есть (вы можете узнать больше об этом с помощью Внутренний размер содержимого).
Следовательно, если вы хотите центрировать UIButton
, a UIlabel
, a UITextField
или UIImageView
внутри UIView
с автоматическим макетом, почти во всех случаях вам не нужно создавать ограничения для их ширины и высоты. Вам просто нужно установить для них горизонтальные и вертикальные ограничения.
Однако при автоматической компоновке UIView
, у которой нет подзаголовков, не может полагаться ни на что, чтобы установить свой размер, если вы не предоставите ему какие-либо произвольные ограничения ширины и высоты. И в соответствии с вашими потребностями вы можете решить это тремя способами.
Стиль чистого макета
Здесь мы устанавливаем ширину и высоту нашего UIView
непосредственно в качестве ограничений макета:
override func viewDidLoad() {
super.viewDidLoad()
let newView = UIView()
newView.backgroundColor = .redColor()
newView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(newView)
// Auto layout code using anchors (iOS9+)
let horizontalConstraint = newView.centerXAnchor.constraintEqualToAnchor(view.centerXAnchor)
let verticalConstraint = newView.centerYAnchor.constraintEqualToAnchor(view.centerYAnchor)
let widthConstraint = newView.widthAnchor.constraintEqualToAnchor(nil, constant: 100)
let heightConstraint = newView.heightAnchor.constraintEqualToAnchor(nil, constant: 100)
NSLayoutConstraint.activateConstraints([horizontalConstraint, verticalConstraint, widthConstraint, heightConstraint])
}
Стиль маскировки авторезистировки
Здесь мы инициализируем наш UIView
с его шириной и высотой, делаем его центр и его центр супервизора равными и создаем несколько масок авторезистировки. Затем мы просим UIKit перевести эти авторезистирующие маски в автоматические ограничения макета:
override func viewDidLoad() {
super.viewDidLoad()
let newView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0))
newView.backgroundColor = .redColor()
newView.center = CGPointMake(view.bounds.midX, view.bounds.midY)
newView.autoresizingMask = [.FlexibleLeftMargin, .FlexibleRightMargin, .FlexibleTopMargin, .FlexibleBottomMargin]
newView.translatesAutoresizingMaskIntoConstraints = true // default is true
view.addSubview(newView)
}
Стиль подкласса
Здесь мы создаем подкласс UIView
и переопределяем его метод intrinsicContentSize()
(объявление), чтобы он возвращал желаемый размер:
import UIKit
class CustomView: UIView {
override func intrinsicContentSize() -> CGSize {
return CGSize(width: 100, height: 100)
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let newView = CustomView()
newView.backgroundColor = .redColor()
newView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(newView)
let horizontalConstraint = NSLayoutConstraint(item: newView,
attribute: .CenterX,
relatedBy: .Equal,
toItem: view,
attribute: .CenterX,
multiplier: 1,
constant: 0)
view.addConstraint(horizontalConstraint)
let verticalConstraint = NSLayoutConstraint(item: newView,
attribute: .CenterY,
relatedBy: .Equal,
toItem: view,
attribute: .CenterY,
multiplier: 1,
constant: 0)
view.addConstraint(verticalConstraint)
}
}