iyOmSd/Title: Swift

[Swift] AutoLayout 코드작성방법 (Visual Format Language, NSLayoutAnchor, NSLayoutConstraint)

냄수 2020. 11. 27. 15:14
반응형

오토레이아웃을 코드로 작성하는 방법에는 3가지가 존재하는데요

 

사용법을 공부해보려고해요

 

같은 레이아웃을 다양한 방법으로 만들어볼건데요

aView(파랑) bView(빨강)이 있고

파란뷰가 좌우 간격 8, 위로20

파란뷰 20 아래에 빨간뷰가 좌우 30

파란뷰, 빨간뷰 모두 크기는 100

간단한 제약사항을 맞춰볼거에요

 

하기전에 기본 설정은 빼먹으면 안돼요 ㅎㅎ

view.addSubview(aView)
view.addSubview(bView)
aView.translatesAutoresizingMaskIntoConstraints = false
bView.translatesAutoresizingMaskIntoConstraints = false
aView.backgroundColor = .blue
bView.backgroundColor = .red

NSLayoutConstraint

인터페이스 객체간에 레이아웃 관계를 나타내구요

문서같은곳에서 보면

 

item1.attribute1 = multiplier × item2.attribute2 + constant

 

이렇게 수식으로 표현되서 적용되는 원리에요

 

제약사항에 맞게 코드를 구현하면

        // NSLayoutConstraint
        // 파란뷰
        NSLayoutConstraint.init(item: aView,
                                attribute: .leading,
                                relatedBy: .equal,
                                toItem: view,
                                attribute: .leading,
                                multiplier: 1.0,
                                constant: 8).isActive = true
        NSLayoutConstraint.init(item: aView,
                                attribute: .top,
                                relatedBy: .equal,
                                toItem: view,
                                attribute: .top,
                                multiplier: 1.0,
                                constant: 20).isActive = true
        NSLayoutConstraint.init(item: aView,
                                attribute: .trailing,
                                relatedBy: .equal,
                                toItem: view,
                                attribute: .trailing,
                                multiplier: 1.0,
                                constant: -8).isActive = true
        NSLayoutConstraint.init(item: aView,
                                attribute: .height,
                                relatedBy: .equal,
                                toItem: nil,
                                attribute: .height,
                                multiplier: 1.0,
                                constant: 100).isActive = true
        
        // 빨간뷰
        NSLayoutConstraint.init(item: bView,
                                attribute: .leading,
                                relatedBy: .equal,
                                toItem: view,
                                attribute: .leading,
                                multiplier: 1.0,
                                constant: 30).isActive = true
        NSLayoutConstraint.init(item: bView,
                                attribute: .top,
                                relatedBy: .equal,
                                toItem: aView,
                                attribute: .bottom,
                                multiplier: 1.0,
                                constant: 20).isActive = true
        NSLayoutConstraint.init(item: bView,
                                attribute: .trailing,
                                relatedBy: .equal,
                                toItem: view,
                                attribute: .trailing,
                                multiplier: 1.0,
                                constant: -30).isActive = true
        NSLayoutConstraint.init(item: bView,
                                attribute: .height,
                                relatedBy: .equal,
                                toItem: nil,
                                attribute: .height,
                                multiplier: 1.0,
                                constant: 100).isActive = true

어우 그냥 보기만해도 기네요....

기니까 세부적인 컨트롤이 가능하겟죠?

 

 

Visual Format Language

레이아웃의 시각적 표현

뷰는 [] (대괄호) 사용

뷰간연결은 - (하이픈)을 사용
NSLayoutConstraint.constraints를 이용

        // Visual Format
        let views: [String : Any] = ["a": aView,
                                     "b": bView]
        let format1 = "H:|-[a]-|"
        let format2 = "H:|-30-[b]-30-|"
        let format3 = "V:|-20-[a(100)]"
        let format4 = "V:[a]-20-[b(100)]"
        
        var constraint = NSLayoutConstraint.constraints(withVisualFormat: format1,
                                                        options: [],
                                                        metrics: nil,
                                                        views: views)
        constraint += NSLayoutConstraint.constraints(withVisualFormat: format2,
                                                     options: [],
                                                     metrics: nil,
                                                     views: views)
        constraint += NSLayoutConstraint.constraints(withVisualFormat: format3,
                                                     options: [],
                                                     metrics: nil,
                                                     views: views)
        constraint += NSLayoutConstraint.constraints(withVisualFormat: format4,
                                                     options: [],
                                                     metrics: nil,
                                                     views: views)
        view.addConstraints(constraint)

보다 짧아졋고, 시각적으로 관계를 파악할 수 있어요

|-8-[a]-8-|

만 봐도

a가 8간격으로 좌우로 잇겟구나 느낌이 있죠

 

하지만 문법이 좀 어려워서 사용하기 힘든 부분이 없지않죠

 

 

NSLayoutAnchor

NSLayoutConstraint가 복잡하고 사용법이 어려워서 새로나온 클래스
NSLayoutConstraint 객체를 만들어내는 팩토리 클래스
간결하고 명확하게 사용가능해요

 

레이아웃을 잡을 때 대부분 사용하는 방법이에요

 

NSLayoutAnchor의 하위클래스로는
NSLayoutXAxisAnchor - 수평 제약
NSLayoutYAxisAnchor - 수직 제약
NSLayoutDimension - 너비, 높이

이 있구요

aView.leadingAnchor.constraint(equalTo: view.leadingAnchor,constant: 8).isActive = true
aView.trailingAnchor.constraint(equalTo: view.trailingAnchor,constant: -8).isActive = true
aView.topAnchor.constraint(equalTo: view.topAnchor,constant: 20).isActive = true
aView.heightAnchor.constraint(equalToConstant: 100).isActive = true
        
bView.leadingAnchor.constraint(equalTo: view.leadingAnchor,constant: 30).isActive = true
bView.trailingAnchor.constraint(equalTo: view.trailingAnchor,constant: -30).isActive = true
bView.topAnchor.constraint(equalTo: aView.bottomAnchor,constant: 20).isActive = true
bView.heightAnchor.constraint(equalToConstant: 100).isActive = true

엄청 간결하게 작성할 수 있죠?

NSLayoutConstraint가 복잡해서 나온 클래스인 만큼 간결하게 만들어 줬어요

 

 

Visual Format Language, NSLayoutAnchor는 결과적으로 NSLayoutConstraint를 사용해요

Visual Format Language는 포맷을 만들어서 NSLayoutConstraint 메서드를 이용해서 적용시켜주고

NSLayoutAnchor를 이용해서 NSLayoutConstraint객체를 생성하고 결국 NSLayoutConstraint를 적용하는거에요

 

 

한번에 비교해보면

왼쪽이 NSLayoutConstraint, 가운데가 Visual Format Language, 오른쪽이 NSLayoutAnchor

반응형