나는 인터넷에서 많은 스 니펫을 찾고 있었지만 여전히 내 문제에 대한 답을 찾을 수 없습니다. 내 질문은 scrollView (SV)가 있고 사용자가 장치 버튼을 회전 할 때 동일한 프레임을 갖도록 해당 superview의 너비와 높이가 동일한 scrollView (SV) 내부에 프로그래밍 방식으로 버튼을 추가하고 싶습니다. scrollView (SV)의. NSLayout / NSLayoutConstraint를 수행하는 방법? 감사
답변:
누군가가 스위프트 솔루션을 찾고 있다면 서브 뷰 프레임을 수퍼 뷰 경계에 바인딩 할 때마다 도움이 될 스위프트 확장을UIView
만들 것입니다.
스위프트 2 :
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.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]))
}
}
스위프트 3 :
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]))
}
}
Swift 4.2 :
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
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
}
}
그런 다음 간단히 다음 과 같이 호출하십시오 .
// after adding as a subview, e.g. `view.addSubview(subview)`
subview.bindFrameToSuperviewBounds()
constant: 0
부품 을 제거하여 조금 더 짧게 만들 수도 있습니다 .
이것이 가장 효율적인 방법인지는 모르겠지만 효과가 있습니다 ..
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];
NSLayoutConstraint.activateConstraints([width, height, top, leading])
[coverForScrolView addConstraints:@[width, height, top, 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)]];
V:|[subview]|
와H:|[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
constant: 0
부품 을 제거하여 조금 더 짧게 만들 수도 있습니다 .
여기의 더 많은 기능 에 접근 스위프트 3 + A를 전제 조건 대신의 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 프레임 워크에 통합 되어 있어 프로젝트에보다 편리한 UI 도우미를 추가합니다.
프로젝트에서 프로그래밍 제약으로 많은 작업을하는 경우 SnapKit 을 확인하는 것이 좋습니다 . 그것은 많은 제약과 협력하게 쉽게 하고 덜 오류가 발생하기 쉬운 .
프로젝트에 SnapKit을 포함하려면 문서 의 설치 지침 을 따르십시오 . 그런 다음 Swift 파일 상단에서 가져옵니다 .
import SnapKit
이제 다음과 같이 똑같은 결과를 얻을 수 있습니다.
subview.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
스위프트 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()
다른 답변에서 최고의 요소를 선택했습니다.
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)
])
}
}
예를 들어 사용자 정의 UIView에서 다음과 같이 사용할 수 있습니다.
let myView = UIView()
myView.backgroundColor = UIColor.red
self.addSubview(myView)
myView.bindFrameToSuperviewBounds()
A는 Dschee의 솔루션 @ 후속으로, 여기에 빠른 3.0 구문입니다 (제발 참고 : 이것은 내 솔루션을하지 , 난 그냥 스위프트 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의 임의의 크기 승수를 사용하여 새로운 것을 작성했습니다. 필요에 따라 자유롭게 변경하십시오. 또한 실제로 이것은 요구 사항과 다를 수있는 수퍼 뷰보다 하위 뷰를 훨씬 더 크게 만듭니다.
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),
])
}
}