위 사진과 같은 화면을 구현하기 위해선 전에 배웠던 constraint(equalTo:...)
메소드를 사용하면 간단히 구현할 수 있다.
제약을 구성할때에 item끼리의 제약 공식을 보면 다음과 같다.
위 사진과 같이 제약공식을 파라미터와 매칭시키면 화살표가 가리키는 것끼리 매칭된다.
item1
-> redView
attr1
-> trailing
item2
-> blueView
attr2
-> leading
여기서 주의할점은 4개의 view 사이의 margin 설정이다.
iOS에서는 화면 오른쪽으로 갈 수록, 아래쪽으로 내려갈수록 x,y 좌표값이 증가하게 된다.
var trailing = NSLayoutConstraint(item: redView,
attribute: .trailing,
relatedBy: .equal,
toItem: blueView,
attribute: .leading,
multiplier: 1.0,
constant: -margin)
이 코드에서 margin값에 -
값을 주어 constant를 설정했다.
그 이유는?
constant값에 양수(+)
를 할당하게 된다면,
blueView의 trailing 위치에서 오른쪽으로 10만큼 움직이기 때문에
아래 그림처럼 view가 겹치기 때문!!
따라서 redView와 blueView를 의도한대로 배치하기 위해 margin값을 음수
로 설정했다.
정확한 설명인지는 잘 모르겠지만,
constraint메소드의 toItem 파라미터에 설정되는 아이탬의 attribute이 기준이 되는 것 같다.var trailing = NSLayoutConstraint(item: redView, attribute: .trailing, relatedBy: .equal, toItem: blueView, attribute: .leading, multiplier: 1.0, constant: -margin)
redView의 trailing이 blueView의 leading의 왼쪽 10만큼 간격을 가져야 하므로
-margin
한거같음! 기준을 잘 생각해서constant
주도록 하자!
어쨋거나 constant를 설정할때만 주의하면 이전에 해왔던 대로 코드를 작성하면 된다.
func layoutWithInitializer() {
redView.translatesAutoresizingMaskIntoConstraints = false
blueView.translatesAutoresizingMaskIntoConstraints = false
yellowView.translatesAutoresizingMaskIntoConstraints = false
blackView.translatesAutoresizingMaskIntoConstraints = false
let margin: CGFloat = 10
// redView
var leading = NSLayoutConstraint(item: redView, attribute: .leading, relatedBy: .equal, toItem: bottomContainer, attribute: .leading, multiplier: 1.0, constant: margin)
var top = NSLayoutConstraint(item: redView, attribute: .top, relatedBy: .equal, toItem: bottomContainer, attribute: .top, multiplier: 1.0, constant: margin)
var trailing = NSLayoutConstraint(item: redView, attribute: .trailing, relatedBy: .equal, toItem: blueView, attribute: .leading, multiplier: 1.0, constant: -margin)
var bottom = NSLayoutConstraint(item: redView, attribute: .bottom, relatedBy: .equal, toItem: yellowView, attribute: .top, multiplier: 1.0, constant: -margin)
NSLayoutConstraint.activate([leading, top, trailing, bottom])
//blueView
top = NSLayoutConstraint(item: blueView, attribute: .top, relatedBy: .equal, toItem: bottomContainer, attribute: .top, multiplier: 1.0, constant: margin)
trailing = NSLayoutConstraint(item: blueView, attribute: .trailing, relatedBy: .equal, toItem: bottomContainer, attribute: .trailing, multiplier: 1.0, constant: -margin)
bottom = NSLayoutConstraint(item: blueView, attribute: .bottom, relatedBy: .equal, toItem: blackView, attribute: .top, multiplier: 1.0, constant: -margin)
NSLayoutConstraint.activate([top, trailing, bottom])
//yellowView
leading = NSLayoutConstraint(item: yellowView, attribute: .leading, relatedBy: .equal, toItem: bottomContainer, attribute: .leading, multiplier: 1.0, constant: margin)
bottom = NSLayoutConstraint(item: yellowView, attribute: .bottom, relatedBy: .equal, toItem: bottomContainer, attribute: .bottom, multiplier: 1.0, constant: -margin)
NSLayoutConstraint.activate([leading, bottom])
//blackView
bottom = NSLayoutConstraint(item: blackView, attribute: .bottom, relatedBy: .equal, toItem: bottomContainer, attribute: .bottom, multiplier: 1.0, constant: -margin)
trailing = NSLayoutConstraint(item: blackView, attribute: .trailing, relatedBy: .equal, toItem: bottomContainer, attribute: .trailing, multiplier: 1.0, constant: -margin)
NSLayoutConstraint.activate([bottom, trailing])
let viewList: [UIView] = [blueView, yellowView, blackView]
for view in viewList{
let width = NSLayoutConstraint(item: view, attribute: .width, relatedBy: .equal, toItem: redView, attribute: .width, multiplier: 1.0, constant: 0)
let height = NSLayoutConstraint(item: view, attribute: .height, relatedBy: .equal, toItem: redView, attribute: .height, multiplier: 1.0, constant: 0)
NSLayoutConstraint.activate([width, height])
}
}
func layoutWithAnchor() {
redView.translatesAutoresizingMaskIntoConstraints = false
blueView.translatesAutoresizingMaskIntoConstraints = false
yellowView.translatesAutoresizingMaskIntoConstraints = false
blackView.translatesAutoresizingMaskIntoConstraints = false
let margin: CGFloat = 10
//redView
redView.leadingAnchor.constraint(equalTo: bottomContainer.leadingAnchor, constant: margin).isActive = true
redView.topAnchor.constraint(equalTo: bottomContainer.topAnchor, constant: margin).isActive = true
redView.trailingAnchor.constraint(equalTo: blueView.leadingAnchor, constant: -margin).isActive = true
redView.bottomAnchor.constraint(equalTo: yellowView.topAnchor, constant: -margin).isActive = true
//blueView
blueView.topAnchor.constraint(equalTo: bottomContainer.topAnchor, constant: margin).isActive = true
blueView.trailingAnchor.constraint(equalTo: bottomContainer.trailingAnchor, constant: -margin).isActive = true
blueView.bottomAnchor.constraint(equalTo: blackView.topAnchor, constant: -margin).isActive = true
//yellowView
yellowView.trailingAnchor.constraint(equalTo: blackView.leadingAnchor, constant: -margin).isActive = true
yellowView.bottomAnchor.constraint(equalTo: bottomContainer.bottomAnchor, constant: -margin)
//blackView
blackView.trailingAnchor.constraint(equalTo: bottomContainer.trailingAnchor, constant: -margin).isActive = true
blackView.bottomAnchor.constraint(equalTo: bottomContainer.bottomAnchor, constant: -margin).isActive = true
let viewList: [UIView] = [blueView, yellowView, blackView]
for view in viewList{
view.widthAnchor.constraint(equalTo: redView.widthAnchor).isActive = true
view.heightAnchor.constraint(equalTo: redView.heightAnchor).isActive = true
}
}
확실히 제약이 많아질수록 Anchor의 사용이 가독성면에서 훨씬 뛰어난 것 같다.
ㅎㅇㅌ!