Jeśli ktoś szuka rozwiązania Swift - stworzyłbym rozszerzenieUIView
Swift, które pomoże ci za każdym razem, gdy chcesz powiązać ramkę subviews z jej granicami superwizji:
Swift 2:
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.constraintsWithVisualFormat("H:|-0-[subview]-0-|", options: .DirectionLeadingToTrailing, metrics: nil, views: ["subview": self]))
superview.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[subview]-0-|", options: .DirectionLeadingToTrailing, metrics: nil, views: ["subview": self]))
}
}
Swift 3:
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.2:
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
self.topAnchor.constraint(equalTo: superview.topAnchor, constant: 0).isActive = true
self.bottomAnchor.constraint(equalTo: superview.bottomAnchor, constant: 0).isActive = true
self.leadingAnchor.constraint(equalTo: superview.leadingAnchor, constant: 0).isActive = true
self.trailingAnchor.constraint(equalTo: superview.trailingAnchor, constant: 0).isActive = true
}
}
Następnie nazwij to tak :
subview.bindFrameToSuperviewBounds()
constant: 0
część.Nie jestem pewien, czy jest to najefektywniejszy sposób, ale działa.
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];
źródło
NSLayoutConstraint.activateConstraints([width, height, top, leading])
[coverForScrolView addConstraints:@[width, height, top, leading]];
Ten link może ci pomóc, postępuj zgodnie z instrukcjami: http://www.raywenderlich.com/20881/beginning-auto-layout-part-1-of-2
EDYTOWAĆ :
użyj następującego fragmentu kodu, gdzie podwidok jest Twoim podziałem.
[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)]];
źródło
V:|[subview]|
iH:|[subview]|
addConstraint
iremoveConstraint
metody dla UIView będą przestarzałe, dlatego warto skorzystać z „udogodnień do tworzenia ograniczeń”: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
źródło
constant: 0
część.Podejście nr 1: rozszerzenie przez UIView
Oto bardziej funkcjonalne podejście w Swift 3+ z warunkiem wstępnym zamiast
print
(który może łatwo zginąć w konsoli). Ten zgłosi błędy programisty jako nieudane kompilacje.Dodaj to rozszerzenie do swojego projektu:
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])) } } }
Teraz po prostu nazwij to tak:
// after adding as a subview, e.g. `view.addSubview(subview)` subview.bindEdgesToSuperview()
Zauważ, że powyższa metoda jest już zintegrowana z moim frameworkiem HandyUIKit , który dodaje również kilka bardziej przydatnych pomocników UI do twojego projektu.
Podejście nr 2: Korzystanie z frameworka
Jeśli dużo pracujesz z ograniczeniami programistycznymi w swoim projekcie, polecam zakup SnapKita . Dzięki temu praca z ograniczeniami jest dużo łatwiejsza i mniej podatna na błędy .
Postępuj zgodnie z instrukcjami instalacji w dokumentacji, aby dołączyć SnapKit do swojego projektu. Następnie zaimportuj go u góry pliku Swift:
import SnapKit
Teraz możesz osiągnąć to samo dzięki temu:
subview.snp.makeConstraints { make in make.edges.equalToSuperview() }
źródło
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])) } }
źródło
Swift 4 przy użyciu
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])
źródło
Jako odpowiedź uzupełniająca i dla tych, którzy nie sprzeciwiają się włączaniu bibliotek innych firm, biblioteka PureLayout zapewnia metodę, która to robi. Po zainstalowaniu biblioteki jest to tak proste, jak
Istnieją inne biblioteki, które również mogą zapewnić podobną funkcjonalność w zależności od gustu, np. Murarstwo , kartografia .
źródło
Z pozostałych odpowiedzi wybrałem najlepsze elementy:
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 NSLayoutConstraint.activate([ self.topAnchor.constraint(equalTo: superview.topAnchor), self.bottomAnchor.constraint(equalTo: superview.bottomAnchor), self.leadingAnchor.constraint(equalTo: superview.leadingAnchor), self.trailingAnchor.constraint(equalTo: superview.trailingAnchor) ]) } }
Możesz go używać w ten sposób, na przykład w swoim niestandardowym UIView:
let myView = UIView() myView.backgroundColor = UIColor.red self.addSubview(myView) myView.bindFrameToSuperviewBounds()
źródło
Jako kontynuacja rozwiązania @ Dschee, oto składnia Swift 3.0: (Uwaga: to nie jest moje rozwiązanie , właśnie to naprawiłem dla 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])) }
źródło
Musiałem całkowicie zakryć nadzór. Inni nie zrobiliby tego podczas zmiany orientacji. Więc napisałem nowy, który to robi - używając dowolnego mnożnika wielkości 20. Możesz dowolnie zmieniać swoje potrzeby. Zwróć również uwagę, że ten w rzeczywistości sprawia, że podgląd podrzędny jest znacznie większy niż podgląd superwizji, który może różnić się od wymagań.
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), ]) } }
źródło