Ширина и высота равны его супервизору, используя autolayout программно?
Я искал много фрагментов в сети, и я все еще не могу найти ответ на свою проблему. Мой вопрос в том, что у меня есть scrollView(SV), и я хочу добавить кнопку внутри scrollView(SV) программно с той же шириной и высотой его супервизора, который является scrollView(SV), чтобы при повороте пользователя кнопка устройства имела тот же кадр scrollView(SV). как сделать NSLayout / NSLayoutConstraint? спасибо
10 ответов
Я не уверен, что это самый эффективный способ сделать это, но он работает..
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.translatesAutoresizingMaskIntoConstraints = NO;
// initialize
[coverForScrolView addSubview:button];
NSLayoutConstraint *width =[NSLayoutConstraint
constraintWithItem:button
attribute:NSLayoutAttributeWidth
relatedBy:0
toItem:coverForScrolView
attribute:NSLayoutAttributeWidth
multiplier:1.0
constant:0];
NSLayoutConstraint *height =[NSLayoutConstraint
constraintWithItem:button
attribute:NSLayoutAttributeHeight
relatedBy:0
toItem:coverForScrolView
attribute:NSLayoutAttributeHeight
multiplier:1.0
constant:0];
NSLayoutConstraint *top = [NSLayoutConstraint
constraintWithItem:button
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:coverForScrolView
attribute:NSLayoutAttributeTop
multiplier:1.0f
constant:0.f];
NSLayoutConstraint *leading = [NSLayoutConstraint
constraintWithItem:button
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:coverForScrolView
attribute:NSLayoutAttributeLeading
multiplier:1.0f
constant:0.f];
[coverForScrolView addConstraint:width];
[coverForScrolView addConstraint:height];
[coverForScrolView addConstraint:top];
[coverForScrolView addConstraint:leading];
эта ссылка может помочь вам, следуйте инструкциям:http://www.raywenderlich.com/20881/beginning-auto-layout-part-1-of-2
изменить :
используйте следующий фрагмент кода, где subview является вашим subivew.
[subview setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"H:|-0-[subview]-0-|"
options:NSLayoutFormatDirectionLeadingToTrailing
metrics:nil
views:NSDictionaryOfVariableBindings(subview)]];
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:|-0-[subview]-0-|"
options:NSLayoutFormatDirectionLeadingToTrailing
metrics:nil
views:NSDictionaryOfVariableBindings(subview)]];
addConstraint
и removeConstraint
методы для UIView будут устаревшими, поэтому стоит использовать "удобства создания ограничений":
view.topAnchor.constraint(equalTo: superView.topAnchor, constant: 0).isActive = true
view.bottomAnchor.constraint(equalTo: superView.bottomAnchor, constant: 0).isActive = true
view.leadingAnchor.constraint(equalTo: superView.leadingAnchor, constant: 0).isActive = true
view.trailingAnchor.constraint(equalTo: superView.trailingAnchor, constant: 0).isActive = true
Подход #1: Через Расширение UIView
здесь более функциональные подход к Swift 3+ С условие вместо print
(который может легко погибнуть в консоли). Этот сообщить об ошибках программиста как не строит.
добавить это расширение проект:
extension UIView {
/// Adds constraints to the superview so that this view has same size and position.
/// Note: This fails the build if the `superview` is `nil` – add it as a subview before calling this.
func bindEdgesToSuperview() {
guard let superview = superview else {
preconditionFailure("`superview` was nil – call `addSubview(view: UIView)` before calling `bindEdgesToSuperview()` to fix this.")
}
translatesAutoresizingMaskIntoConstraints = false
["H:|-0-[subview]-0-|", "V:|-0-[subview]-0-|"].forEach { visualFormat in
superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: visualFormat, options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self]))
}
}
}
теперь просто называю это как это:
// after adding as a subview, e.g. `view.addSubview(subview)`
subview.bindEdgesToSuperview()
обратите внимание, что вышеуказанным способом уже интегрированы в свою HandyUIKit framework, который также добавляет еще несколько удобных помощников UI в ваш проект.
подход #2: использование фреймворка
если вы много работать с программными ограничениями в вашем проекте, то я рекомендую вам оформить заказ SnapKit. Это делает работу с ограничениями много легче и меньше ошибок.
следуя инструкция по установке в документах для включения SnapKit в ваш проект. Тогда импорт это в верхней части вашего файла SWIFT:
import SnapKit
теперь вы можете достичь того же самого только с этим:
subview.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
Swift 3:
import UIKit
extension UIView {
func bindFrameToSuperviewBounds() {
guard let superview = self.superview else {
print("Error! `superview` was nil – call `addSubview(view: UIView)` before calling `bindFrameToSuperviewBounds()` to fix this.")
return
}
self.translatesAutoresizingMaskIntoConstraints = false
superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self]))
superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self]))
}
}
Swift 4 используя NSLayoutConstraint
:
footerBoardImageView.translatesAutoresizingMaskIntoConstraints = false
let widthConstraint = NSLayoutConstraint(item: yourview, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: superview, attribute: NSLayoutAttribute.width, multiplier: 1, constant: 0)
let heightConstraint = NSLayoutConstraint(item: yourview, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: superview, attribute: NSLayoutAttribute.height, multiplier: 1, constant: 0)
superview.addConstraints([widthConstraint, heightConstraint])
в качестве дополнительного ответа и для тех, кто не против включения сторонних библиотек,PureLayout библиотека предоставляет метод для этого. После установки библиотеки это так же просто, как
myView.autoPinEdgesToSuperviewEdges()
есть другие библиотеки, которые могут обеспечить аналогичную функциональность, а также в зависимости от вкуса, например. кладка, картография.
как продолжение решения @Dschee, вот синтаксис swift 3.0: (Обратите внимание: это не мое решение, Я только что установил его для Swift 3.0)
extension UIView {
/// Adds constraints to this `UIView` instances `superview` object to make sure this always has the same size as the superview.
/// Please note that this has no effect if its `superview` is `nil` – add this `UIView` instance as a subview before calling this.
func bindFrameToSuperviewBounds() {
guard let superview = self.superview else {
print("Error! `superview` was nil – call `addSubview(view: UIView)` before calling `bindFrameToSuperviewBounds()` to fix this.")
return
}
self.translatesAutoresizingMaskIntoConstraints = false
superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self]))
superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self]))
}
Мне нужно было полностью закрыть обзор. Другие не стали бы этого делать во время смены ориентации. Поэтому я написал новый, который делает - используя произвольный множитель размера 20. Не стесняйтесь меняться в соответствии с вашими потребностями. Также обратите внимание, что это на самом деле делает subview намного больше, чем superview, который может отличаться от требований.
extension UIView {
func coverSuperview() {
guard let superview = self.superview else {
assert(false, "Error! `superview` was nil – call `addSubview(_ view: UIView)` before calling `\(#function)` to fix this.")
return
}
self.translatesAutoresizingMaskIntoConstraints = false
let multiplier = CGFloat(20.0)
NSLayoutConstraint.activate([
self.heightAnchor.constraint(equalTo: superview.heightAnchor, multiplier: multiplier),
self.widthAnchor.constraint(equalTo: superview.widthAnchor, multiplier: multiplier),
self.centerXAnchor.constraint(equalTo: superview.centerXAnchor),
self.centerYAnchor.constraint(equalTo: superview.centerYAnchor),
])
}
}