Constraints with Code #1
Constraints with Code #0 에서 작성했던
NSLayoutConstraint 와 NSLayoutAnchor를 이용해 직접 화면을 구성해보자.
우선, 화면을 절반으로 나누고 아래의 View를 위의 View와 동일하게 출력되게끔 코드로 직접 제약을 생성해보자.
우선, NSLayoutConstraint 와 NSLayoutAnchor 를 테스트해볼거니까 extension해서 따로따로 함수를 만들자.
- layoutWithInitializer() -> NSLayoutConstraint
- layoutWithAnchor() -> NSLayoutAnchor
NSLayoutConstraint 를 이용한 방법
extension FillParentViewController {
func layoutWithInitializer() {
blueView.translatesAutoresizingMaskIntoConstraints = false // #1
let leading = NSLayoutConstraint(item: blueView, attribute: .leading, relatedBy: .equal, toItem: bottomContainer, attribute: .leading, multiplier: 1.0, constant: 0)
let top = NSLayoutConstraint(item: blueView, attribute: .top, relatedBy: .equal, toItem: bottomContainer, attribute: .top, multiplier: 1.0, constant: 0)
let trailing = NSLayoutConstraint(item: blueView, attribute: .trailing, relatedBy: .equal, toItem: bottomContainer, attribute: .trailing, multiplier: 1.0, constant: 0)
let bottom = NSLayoutConstraint(item: blueView, attribute: .bottom, relatedBy: .equal, toItem: bottomContainer, attribute: .bottom, multiplier: 1.0, constant: 0)
NSLayoutConstraint.activate([leading,top,trailing,bottom])
}
}
-
NSLayoutConstraint를 이용해 원하는 제약을 생성하고, activate 메소드를 통해 제약을 활성화 하는 방식으로 사용한다.
-
이 activate 메소드는 활성화 할 제약을 배열로 전달받아 올바른 위치에 자동으로 추가해준다.
!! 여기서 주의할 점
#1 의 코드를 작성하지 않게되면 내가 원하지 않는 결과가 출력된다.
why??
-
viewController안에 blueView는 코드로 제약을 생성하기전까지 아무런 제약없이 놓여있기 때문이다.
-
이런 경우, 인터페이스 빌더가 알아서 NSAutoresizingMaskLayoutConstraint 을 기반으로 제약을 자동으로 추가한다.
-
그렇기 때문에 내가 생성해서 적용한 제약과 NSAutoresizingMaskLayoutConstraint을 을 기반으로 자동으로 추가된 제약이 충돌을 일으키기 때문이다.
해결을 위해선 #1 의 코드처럼 translatesAutoresizingMaskIntoConstraints을 사용하지 않는다고 선언해주면 된다.
blueView.translatesAutoresizingMaskIntoConstraints = false // #1
NSLayoutAnchor 를 이용한 방법
extension FillParentViewController {
func layoutWithAnchor() {
blueView.translatesAutoresizingMaskIntoConstraints = false
blueView.leadingAnchor.constraint(equalTo: bottomContainer.leadingAnchor).isActive = true// #1
blueView.trailingAnchor.constraint(equalTo: bottomContainer.trailingAnchor).isActive = true
blueView.topAnchor.constraint(equalTo: bottomContainer.topAnchor).isActive = true
blueView.bottomAnchor.constraint(equalTo: bottomContainer.bottomAnchor).isActive = true
}
}
NSLayoutConstraint 을 이용한 방식보다 훨씬 간단하다!
-
각각의 제약은 View가 가지고 있는 Anchor 속성으로 지정할 수 있다.
-
각각의 Anchor 속성은 다양한 메소드를 제공한다.
-
#1 과 같이 constraint 메소드에 SuperView의 원하는 Anchor속성을 전달하며느 그 앵커를 기준으로 relation 이 equal이고 constant 가 0인 제약이 추가된다.
NSLayoutConstraint 방식과 마찬가지로 NSLayoutAnchor 도 꼭 translatesAutoresizingMaskIntoConstraints을 사용하지 않는다고 선언해줘야 한다.
blueView.translatesAutoresizingMaskIntoConstraints = false
결과 화면
두 방식을 비교해보자 ㅎㅋㅎㅋ
같은 제약을 생성해 같은 화면을 구성했지만 두 방식의 코드 구현을 살펴보면
NSLayoutConstraint
extension FillParentViewController {
func layoutWithInitializer() {
blueView.translatesAutoresizingMaskIntoConstraints = false // #1
let leading = NSLayoutConstraint(item: blueView,
attribute: .leading,
relatedBy: .equal,
toItem: bottomContainer,
attribute: .leading,
multiplier: 1.0,
constant: 0)
let top = NSLayoutConstraint(item: blueView,
attribute: .top,
relatedBy: .equal,
toItem: bottomContainer,
attribute: .top,
multiplier: 1.0,
constant: 0)
let trailing = NSLayoutConstraint(item: blueView,
attribute: .trailing,
relatedBy: .equal,
toItem: bottomContainer,
attribute: .trailing,
multiplier: 1.0,
constant: 0)
let bottom = NSLayoutConstraint(item: blueView,
attribute: .bottom,
relatedBy: .equal,
toItem: bottomContainer,
attribute: .bottom,
multiplier: 1.0,
constant: 0)
NSLayoutConstraint.activate([leading,top,trailing,bottom])
}
}
NSLayoutAnchor
extension FillParentViewController {
func layoutWithAnchor() {
blueView.translatesAutoresizingMaskIntoConstraints = false
blueView
.leadingAnchor
.constraint(equalTo: bottomContainer.leadingAnchor)
.isActive = true// #1
blueView
.trailingAnchor
.constraint(equalTo: bottomContainer.trailingAnchor)
.isActive = true
blueView
.topAnchor
.constraint(equalTo: bottomContainer.topAnchor)
.isActive = true
blueView
.bottomAnchor
.constraint(equalTo: bottomContainer.bottomAnchor)
.isActive = true
}
}
훠어얼씬 가독성도 좋고 간단하게 구현할 수 있다는걸 알 수 있다 !
Author And Source
이 문제에 관하여(Constraints with Code #1), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@tnddls2ek/Constraints-with-Code-1저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)