-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
<4주차> 오토레이아웃을 코드로 작성하는 방법은 무엇인가? (3가지) #20
Comments
1. NSLayoutConstraint 사용 NSLayoutConstraint.activate([NSLayoutConstraint(item: UIButton, attribute: .centerX, relatedBy: .equal, toItem: UIView, attribute: .centerX, multiplier: 1.0, constant: 0.0), ...]) 2. Visual Format Language 사용 NSLayoutConstraint.activate([NSLayoutConstraint.constraints(withVisualFormat: "H:[button(200)]", options: .alignAllCenterX, metrics: nil, views: ["button": button]), ...) 3. Anchor 사용 NSLayoutConstraint.activate([button.centerXAnchor.constraint(equalTo: view.centerXAnchor), ...]) 4. 이 외에 SnapKit과 같은 라이브러리를 사용할 수 있다. |
NSLayoutConstraint제약 기반 레이아웃 시스템에서 충족해야하는 두 사용자 인터페이스(UI) 개체 간의 관계입니다. item1.attribute1 = multiplier × item2.attribute2 + constant
button2.leading = 1.0 × button1.trailing + 8.0
//다른 아이템과의 관계로서 layout 정의 AnchortranslatesAutoresizingMastIntoConstraints = false
//기존의 오토리사이징마스크와 충돌을 없애기 위해 설정
var constraintY: NSLayoutConstraint
constraintY = button.centerYAnchor.constraint(equalTo: self.view.centerYAnchor) Visual Format Language (처음 알게 됨)기호 및 문자열로 레이아웃 관계 표시 |
convenience init(item view1: Any,
attribute attr1: NSLayoutConstraint.Attribute,
relatedBy relation: NSLayoutConstraint.Relation,
toItem view2: Any?,
attribute attr2: NSLayoutConstraint.Attribute,
multiplier: CGFloat,
constant c: CGFloat)
let views = ["redView": redView,
"blueView": blueView,
"greenView": greenView]
let format1 = "V:|-[redView]-8-[greenView]-|"
let format2 = "H:|-[redView]-8-[blueView(==redView)]-|"
let format3 = "H:|-[greenView]-|"
var constraints = NSConstraint.constraints(withVisualFormat: format1,
options: alignAllLeft,
matrics: nil,
views: views)
constraints += NSConstraint.constraints(withVisualFormat: format2,
options: alignAllTop,
matrics: nil,
views: views)
constraints += NSConstraint.constraints(withVisualFormat: format3,
options: []
matrics: nil,
views: views)
NSConstraint.activateConstraints(constraints) 출처 : 블로그 |
myView.translatesAutoresizingMastIntoConstraints = false let margins = view.layoutMarginsGuide
myView.leadingAnchor.constraint(equalTo: margins.leadingAnchor).active = true
myView.trailingAnchor.constraint(equalTo: margins.trailingAnchor).active = true
myView.heightAnchor.constraint(equalTo: myView.widthAnchor, multiplier: 2.0)
NSLayoutConstraint(item: myView, attribute: .leading, relatedBy: .Equal, toItem: view, attribute: .leadingMargin, multiplier: 1.0, constant: 0.0).isActive = true
let views = ["myView": myView]
let formatString = "|-[myView]-|"
let constraints = NSLayoutConstraint.constraintsWithVisualFormat(formatString,
options: .AlignAllTop,
metrics: nil,
views: views)
NSLayoutConstraint.activateConstraints(constraints)
|
3가지가 존재하고 NSLayoutConstraint
Visual Format Language NSLayoutAnchor aView.leadingAnchor.constraint(equalTo: leftLabel.leadingAnchor,constant: 10).isActive = true Visual Format Language, NSLayoutAnchor는 결과적으로 NSLayoutConstraint를 사용 비교코드 func layout() {
view.addSubview(aView)
view.addSubview(bView)
aView.translatesAutoresizingMaskIntoConstraints = false
bView.translatesAutoresizingMaskIntoConstraints = false
aView.backgroundColor = .blue
bView.backgroundColor = .red
// Visual Format
let views: [String : Any] = ["a": aView,
"b": bView]
let format1 = "H:|-8-[a]-8-|"
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)
//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
//NSLayoutAnchor
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.activate([
alertView.centerYAnchor.constraint(equalTo: window.centerYAnchor),
alertView.leadingAnchor.constraint(equalTo: window.leadingAnchor, constant: 20),
alertView.trailingAnchor.constraint(equalTo: window.trailingAnchor, constant: -20),
]) 특정 Anchor를 지정해서 오토레이아웃을 잡는 방식인데, 배열 바깥에서 알 수 있듯 NSLayoutConstraint를 사용해서 active 시킵니당 특징
단점
NSLayoutConstraint(item: alertView,
attribute: .leading,
relatedBy: .equal,
toItem: messageLabel,
attribute: .leading,
multiplier: 1.0,
constant: 8).isActive = true 이런식으로 item, toItem을 지정해서 짭니다. 특징 고고 특징
단점
그래서 저는 이런 커스텀메소드를 만들어서 쓰는뎅 좋은듯해요 extension UIView {
// 1
func constraint(to view: UIView,
attribute: NSLayoutConstraint.Attribute,
secondAttribute: NSLayoutConstraint.Attribute,
inset: CGFloat = 0) {
self.translatesAutoresizingMaskIntoConstraints = false
let c = NSLayoutConstraint(item: self,
attribute: attribute,
relatedBy: .equal,
toItem: view,
attribute: secondAttribute,
multiplier: 1,
constant: inset)
c.isActive = true
}
// 2
func constraint(_ anchor: NSLayoutDimension, constant: CGFloat) {
self.translatesAutoresizingMaskIntoConstraints = false
anchor.constraint(equalToConstant: constant).isActive = true
}
이렇게 해놓고 // 1
dismissButton.constraint(to: alertView,
attribute: .trailing,
secondAttribute: .trailing,
inset: -12)
dismissButton.constraint(to: alertView,
attribute: .top,
secondAttribute: .top,
inset: 12)
// 2
dismissButton.constraint(widthAnchor, constant: 44)
dismissButton.constraint(heightAnchor, constant: 44) 이런식으로 씁니당. 나쁘지 않아요~~
또한 오토레이아웃 잘못 잡으면 디버깅창에 뜨는 오토레이아웃 에러메시지가 VFL로 뜹니다!!! 그래서 배워놓으면 좋을듯 한데 저는 모름
특징
단점
https://iosexample.com/ios-auto-layout-with-json-and-vfl/ |
2019년도 Let's Swift 강의 https://www.youtube.com/watch?v=EzjyuEf61Vo&list=PLAHa1zfLtLiOiVcIUwWZbOgN9x3cTjRqN&index=9 를 기반으로 작성합니당~
Layout을 code로 작성하기 위해서 나온 레이아웃 작성 방식 아래의 예시로 보면 알수있겠지만 코드 한줄 한줄 의미하는게 한눈에 보이고 좋지만 코드의 가독성이 좋지 않다. NSLayoutConstraint.activate([
NSLayoutConstraint(item: button,
attribute: .centerX,
relatedBy: .equal,
toItem: view,
attribute: .centerX,
multiplier: 1.0,
constant: 0.0),
NSLayoutConstraint(item: button,
attribute: .width,
relatedBy: .equal,
toItem: nil,
attribute: .height,
multiplier: 1.0,
constant: 200.0),
NSLayoutConstraint(item: button,
attribute: .top,
relatedBy: .equal,
toItem: view,
attribute: .topMargin,
multiplier: 1.0,
constant: 100.0),
NSLayoutConstraint(item: button,
attribute: .height,
relatedBy: .equal,
toItem: view,
attribute: .height,
multiplier: 1.0,
constant: 80.0)
])
아직 사용해본적은 없는 레이아웃 구조를 잡는 방식이지만, 익숙해지면... 간편할것만 같은 작성 방법... 문법에 대한 공부가 필요함... *** 제일 큰 단점 NSLayoutConstraint.activate([
NSLayoutConstraint.constraints(withVisualFormat: "H:[button(200)]",
options: .alignAllCenterX,
metrics: nil,
views: ["button": button]),
NSLayoutConstraint.constraints(withVisualFormat: "V:[sv]-(<=1.0)-[button(80)]",
options: .alignAllCenterX,
metrics: nil,
views: ["sv": view!, "button": button]),
NSLayoutConstraint.constraints(withVisualFormat: "V:|-(100)-[button(80)]",
options: .alignAllTop,
metrics: nil,
views: ["button": button])
].flatMap({ $0 }))
NSLayoutConstraint으로 작성한 코드 방식이 굉장히 가독성이 떨어지기 때문에 나온 레이아웃 코드 방식 위 두개에 비해서는 가독성이 나쁘지 않는 듯! NSLayoutConstraint.activate([
button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
button.widthAnchor.constraint(equalToConstant: 200.0),
button.topAnchor.constraint(equalTo: view.topAnchor, constant: 100.0),
button.heightAnchor.constraint(equalToConstant: 80.0)
]) |
Anchor라는 개념을 통해 NSLayoutConstraint를 생성시킬 수 있다. Anchor와 관련된 프로퍼티 var constraints: [NSLayoutConstrint] // 뷰에 부여한 제약사항들을 담은 배열
var bottomAnchor: NSLayoutYAxisAnchor { get } // 뷰 프레임의 하단부 레이아웃 앵커
var centerXAnchor: NSLayoutXAxisAnchor { get } // 뷰 프레임의 수평 중심부 레이아웃 앵커
var centerYAnchor: NSLayoutYAxisAnchor { get } // 뷰 프레임의 수직 중심부 레이아웃 앵커
var heightAnchor: NSLayoutDimension { get }// 뷰 프레임의 높이를 가리키는 레이아웃 앵커
var leadingAnchor: NSLayoutXAxisAnchor { get } // 뷰 프레임의 리딩을 가리키는 레이아웃 앵커
var topAnchor: NSLayoutYAnchor { get } // 뷰 프레임의 상단부 레이아웃 앵커
var trailingAnchor: NSLayoytXAxisAnchor { get } // 뷰 프레임의 트레일링을 가리키는 레이아웃 앵커
var widthAnchor: NSLayoutDimension { get }// 뷰 프레임의 넓이를 가리키는 레이아웃 앵커 직접 사용한 예제 // Set Label’s width
var widthConstraint: NSLayoutConstraint
widthConstraint = label.widthAnchor.constraint(equalTo: Button.widthAnchor, multiplier: 2.0)
widthConstraint.isActive = true 다음을 통해 NSLayoutConstraint를 생성하여 isActive 해주거나 NSLayoutConstraint.activate([
label.widthAnchor.constraint(equalTo: Button.widthAnchor, multiplier: 2.0)
]) 다음과 같이 배열을 통해 전체를 active 시켜주는 방법이 있다.
centerY = NSLayoutConstraint(item: button,
attribute: .centerY,
relatedBy: .equal,
toItem: self.view,
attribute: .centerY,
multiplier: 0.8,
constant: 0) 다음과 같이 오토레이아웃 방정식의 각 속성들을 지정하여 생성할 수 있다. active해주는 방식은 anchor방식과 유사하다고 볼 수 있다.
VFL에서 사용 가능한 기호 및 문자열의 의미 |
No description provided.
The text was updated successfully, but these errors were encountered: