iPhone Application 씬의 변화에 따른 제약조건

  1. 씬이 변화되는 경우는 아래와 같다.
    1. 기기의 회전 : 기기를 세로 또는 가로로 회전하여 씬의 변화를 준다.

    2. 다른 화면 크기/배율의 기기에서 동작 : iPhone SE, iPhone X 등 화면의 크기와 배율이 다를 경우 씬의 변화가 생기게 된다.
    3. 동적인 씬 레이아웃 변화 : 세그먼티드 컨트롤처럼 다른 씬을 출력하는 경우 씬의 변화가 생기게 된다.
  2. 씬에 변화가 생겨도 제약조건을 주어서 씬의 변화에 대응하도록 할 수 있다.
    1. 기기를 회전 시에도 버튼이 출력되도록 할 수 있다.
  3. 제약 조건 작성
    1. 제약 조건은 씬의 구조에 따라서 컨텐츠 영역이 변경되게 되는데 이런 변화에 대응할 수 있게 새로운 프레임을 적용하도록 한다.
    2. 종류
      1. 레이아웃 가이드 : 씬의 구조에 따라서 컨텐츠 영역이 변경되는데 레이아웃을 참조하여 컨텐츠 영역을 결정한다. (Top / Bottom / Left / Right)

      2. 컨텐츠 마진 : 컨텐츠 배치의 기준선으로 컨텐츠가 화면에 어느 정도 떨어진 후에 배치가 되는지에 대한 여유 공간의 거리이다. (아래 빨간색 선이 컨텐츠 마진을 나타낸 선이다.)

      3. 컨텐츠의 위치잡기 : 4 방향의 거리, 부모 뷰와의 거리, 중앙 위치, 형제 뷰와의 거리를 통해서 컨텐츠의 위치를 잡게 된다.

      4. 제약 조건이 적용되는 시점은 뷰 컨트롤러의 레이아웃 적용 라이프 사이클에서 viewWillLayoutSubviews, viewDidLayoutSubviews 함수에서 적용된다.
      5. Storyboard에서 제약 조건 작성
        1. Storyboard에서는 아래 그림처럼 메뉴를 통해서 제약조건을 작성한다. : Update Frame, Stackview, Align, Add new Constraints, Resolve Auto Layout Issues

        2. 작성된 제약 조건 확인은 아래 그림에서 Constraints에서 확인할 수 있다.

      6. 코드로 제약 조건 작성
        1. 제약 조건 관련 클래스 NSLayoutContraint 로 제약 조건을 작성한다.
          1. init 메소드는 아래와 같다.

          2. NSLayoutAttribute 클래스 : top, bottom, leading, trailing, width, height 에 대한 제약 조건을 작성할 수 있다.
          3. NSLayoutRelation 클래스 : lessThanOrEqual, equal, greaterThanOrEqual 에 대한 제약 조건을 작성할 수 있다.
          4. 코드로 작성한 예시는 아래와 같다.
            제약 조건을 코드로 작성한 예시

            let label = UILabel() self.view.addSubview(label)
            //
            오토 리사이즈로 인한 제약조건 생성 막기label.translatesAutoresizingMaskIntoConstraints = false 

            // 왼쪽으로 20 포인트 여백

            let leftConstraint = NSLayoutConstraint(item: label, attribute: NSLayoutAttribute.leading, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.leadingMargin, multiplier: 1.0, constant: 20)

            // 씬 상단 레이아웃 가이드와 20포인트 여백
            let topConstraint = NSLayoutConstraint(item: label, attribute: .top, relatedBy: .equal, toItem: self.topLayoutGuide, attribute: .bottom, multiplier: 1.0, constant: 20)

            // 부모뷰에 제약조건 객체 추가 label.superview!.addConstraints([leftConstraint, topConstraint])

            // 크기 제약조건
            let widthConstraint = NSLayoutConstraint(item: label, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 300)

            // 해당 뷰에 제약조건 추가 label.addConstraint(widthConstraint) 

        2. 비주얼 포맷 언어 : 기호 언어에서 제약 조건 객체를 만들어준다.
          1. 사용 기호 : |, -
          2. 사용 방법
            1. 거리 지정 (H : 가로, V : 세로)
              비주얼 포맷 언어 거리 지정
              // 가장 왼쪽과 버튼과의 거리 지정
              |-[Button]

              // 버튼을 가장 왼쪽부터 50만큼 떨어져 배치
              |-50-[Button]

              // 가장 위쪽과 버튼과의 거리 지정
              V:|-[Button]

              // 버튼을 가장 위쪽부터 70만큼 떨어져 배치
              V:|-70-[Button]
            2. 크기(괄호), 중요도(@ 기호)
              비주얼 포맷 언어로 크기 및 중요도 지정
              // 버튼 크기를 100으로 지정
              |-50-[Button(100)]

              // 버튼 크기를 50으로 지정하고 중요도 지정
              V:|-100-[Button(50@750)]
            3. 뷰 간 거리
              비주얼 포맷 언어로 뷰 간 거리 지정
              // ButtonA와 ButtonB 간 거리 지정
              [ButtonA]-[ButtonB]

              // ButtonA와 ButtonB 간 거리를 20만큼 떨어져 지정
              [ButtonA]-20-[ButtonB]

              // ButtonA와 ButtonB 간 거리를 상하로 20만큼 떨어져 지정
              V:[ButtonA]-20-[ButtonB]
          3. 비주얼 포맷 언어를 사용한 예시는 아래와 같다.
            비주얼 포맷 언어로 작성한 제약 조건

            let label1 = UILabel() self.view.addSubview(label1) let label2 = UILabel() self.view.addSubview(label2)

            // 오토 리사이즈로 인한 제약조건 생성 막기label1.translatesAutoresizingMaskIntoConstraints = false 

            label2.translatesAutoresizingMaskIntoConstraints = false

            // 비주얼 포맷 언어에서 사용하는 뷰
            let views = ["label1":label1, "label2":label2, "topGuide":self.topLayoutGuide]

            // 비주얼 포맷 언어로 제약조건 객체 생성
            let horizontalConstraints = NSLayoutConstraint.constraints(withVisualFormat:"|-20-[label1]-20-[label2]", options:[], metrics: nil, views: views)

            let verticalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:[topGuide]-100-[label1][label2]", options:[], metrics: nil, views: views)

            // 부모뷰에 제약조건 추가label.superview!.addConstraints(horizontalConstraints) label.superview!.addConstraints(verticalConstraints