Constraints with Code # 3 - 2

이숭인·2021년 7월 16일
0

Mastering iOS

목록 보기
8/11

width, height가 같고 top, trailing, leading, bottom 의 margin이 일정하도록 constraint를 설정해보자.

위 사진과 같은 화면을 구현하기 위해선 전에 배웠던 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를 설정할때만 주의하면 이전에 해왔던 대로 코드를 작성하면 된다.

완성 코드:

  • NSLayoutConstraint
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])
    }
   }
  • NSLayoutAnchor
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의 사용이 가독성면에서 훨씬 뛰어난 것 같다.
ㅎㅇㅌ!

profile
iOS Developer

0개의 댓글