티스토리 뷰
iOS
[iOS 오토레이아웃 가이드] Advanced Auto Layout - Programmatically Creating Constraints
rhinoPHS 2018. 8. 7. 17:06[iOS 오토레이아웃 가이드] Advanced Auto Layout - Programmatically Creating Constraints
코드로 오토리아웃을 구현하는 방법은 3가지 입니다.
Layout Anchors
View의 다양한 Anchor들을 가지고 하는 방식입니다. topAnchor, bottomAnchor, heightAnchor등이 있습니다. topAnchor는 뷰의 top edge를 가리킵니다.
https://developer.apple.com/documentation/uikit/uiview - Creating Constraints Using Layout Anchors 보시면 모든 anchors가 나와있습니다.
3개 방법 중 가독성이 좋다고 생각합니다.
apple 문서에 나와있는 예제를 보도록 하겠습니다.
Listing 13-1Creating layout anchors
// Get the superview's layout
let margins = view.layoutMarginsGuide
// Pin the leading edge of myView to the margin's leading edge
myView.leadingAnchor.constraint(equalTo: margins.leadingAnchor).isActive = true
// Pin the trailing edge of myView to the margin's trailing edge
myView.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true
// Give myView a 1:2 aspect ratio
myView.heightAnchor.constraint(equalTo: myView.widthAnchor, multiplier: 2.0).isActive = true
Layout anchor에는 많은 메소드가 있습니다. NSLayoutAnchor genetic class보시면 됩니다.
https://developer.apple.com/documentation/appkit/nslayoutanchor
사용은 다음과 같습니다.
myView.leadingAnchor.constraint(equalTo: margins.leadingAnchor).isActive = true
Equation | Symbol |
---|---|
Item 1 | myView |
Attribute 1 | leadingAnchor |
Relationship | constraintEqualToAnchor |
Multiplier | None (defaults to 1.0) |
Item 2 | margins |
Attribute 2 | leadingAnchor |
Constant | None (defaults to 0.0) |
NSLayoutConstraint Class
init(item:attribute:relatedBy:toItem:attribute:multiplier:constant:)를 이용해서 할 수도 있습니다. 위에 나온 Equation을 그대로 사용합니다.
NSLayoutConstraint(item: myView, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leadingMargin, multiplier: 1.0, constant: 0.0).isActive = true
NSLayoutConstraint(item: myView, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailingMargin, multiplier: 1.0, constant: 0.0).isActive = true
NSLayoutConstraint(item: myView, attribute: .height, relatedBy: .equal, toItem: myView, attribute:.width, multiplier: 2.0, constant:0.0).isActive = true
하지만 읽기 힘듭니다. 실수하기도 쉽습니다. iOS8이나 OS X v10.10 이전 버전을 지원하지 않아도 된다면 layout anchor를 사용하기를 권장합니다.
Visual Format Language
제약조건을 ASCII-art같이 만듭니다. 장단점은 다음과 같습니다.
- 제약조건이 콘솔에 Visual Format Language(이하 VFL)로 나오기 때문에 알아두면 좋습니다.
- VFL를 사용하면 여러 제약조건을 한 번에 만들 수 있습니다.
- VFL는 유효한 제약조건만을 만들게 합니다.
- VFL로는 aspect ratios같은 제약조건을 만들 수 없습니다.
- VFL의 문제는 런타임 테스트 때 알 수 있습니다
let views = ["myView" : myView]
let formatString = "|-[myView]-|"
let constraints = NSLayoutConstraint.constraints(withVisualFormat: formatString, options: .alignAllTop, metrics: nil, views: views)
NSLayoutConstraint.activate(constraints)
위 제약조건은 leading과 trailing 제약조건을 만듭니다. 기본 spacing을 사용하면 VFL는 항상 슈퍼뷰 마진에 0-point 제약조건을 만듭니다. 따라서 NSLayoutconstraint 예제와 같습니다.
VFL를 만드는 순서는
1. 뷰 dictionary를 만듭니다. dictionary는 key로 string과 value로 뷰가 있어야 합니다.
swift에서는 직접만들어야 하지만 objc에서는 NSDictionaryOfVariableBindings 매크로가 생성해줍니다.
2 (선택) metrics dictionary를 만듭니다. 이것 또한 key로 string, value로는 NSNumber로 돼 있어야 합니다.
3. format string을 만듭니다.
4. NSLayoutConstraint.constraint(widthVisualFormat:options:metrics:views)를 호출합니다. 이 함수는 제약조건 배열을 리턴합니다.
5. NSLayoutConstraint.activate를 통해서 만든 제약조건들을 활성화 시킵니다.
보다 자세한 사항
https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/VisualFormatLanguage.html#//apple_ref/doc/uid/TP40010853-CH27-SW1