swift snapkit edges 헷갈리는 inset offset 용어 알아보자.
snapkit 사용을 안해보고 바꿔 볼려고 하다가
contentLabel.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
처음보는... edge
이게 먼가 해서 찾아봤다.
공식 문서답.
https://developer.apple.com/documentation/swiftui/edge
Edge | Apple Developer Documentation
An enumeration to indicate one edge of a rectangle.
developer.apple.com
SnapKit은 Swift에서 Auto Layout 제약 조건을 더 간결하게 선언할 수 있게 도와주는 라이브러리입니다. SnapKit을 사용하면 복잡한 NSLayoutConstraint 코드를 훨씬 단순하게 만들 수 있습니다.
아래에 SnapKit의 기본 사용 방법에 대해 설명하겠습니다:
- 기본 구조:
SnapKit은 make, remake, update라는 세 가지 주요 함수로 구성됩니다.
makeConstraints: 새로운 제약 조건을 생성합니다.
updateConstraints: 기존 제약 조건을 수정합니다.
remakeConstraints: 기존 제약 조건을 제거하고 새로운 제약 조건을 생성합니다.
- 기본 제약 조건 설정:
뷰에 제약 조건을 추가하려면 makeConstraints 메서드를 사용하십시오.
view.snp.makeConstraints { (make) in
make.width.equalTo(100)
make.height.equalTo(50)
}
- 상대적인 제약 조건:
다른 뷰나 상위 뷰에 대한 상대적인 제약 조건을 쉽게 설정할 수 있습니다.
view.snp.makeConstraints { (make) in
make.top.equalTo(superview.snp.top).offset(20)
make.left.equalTo(superview.snp.left).offset(15)
}
- 연산자 사용:
SnapKit은 연산자를 활용하여 제약 조건을 더욱 명확하게 만들 수 있습니다.
view.snp.makeConstraints { (make) in
make.width.equalToSuperview().multipliedBy(0.5).offset(-10)
make.height.lessThanOrEqualTo(200)
make.height.greaterThanOrEqualTo(100)
}
- 중심, 크기 및 가장자리:
SnapKit을 사용하여 뷰의 중심, 크기, 가장자리에 대한 제약 조건을 쉽게 설정할 수 있습니다.
view.snp.makeConstraints { (make) in
make.center.equalTo(superview)
make.size.equalTo(CGSize(width: 100, height: 50))
make.edges.equalTo(superview).inset(20)
}
- 배열 및 마진 제약 조건:
배열을 사용하여 여러 뷰에 대한 제약 조건을 쉽게 설정하거나 마진을 사용하여 제약 조건을 설정할 수 있습니다.
let views = [view1, view2, view3]
views.snp.makeConstraints { (make) in
make.height.equalTo(50)
}
view1.snp.makeConstraints { (make) in
make.leadingMargin.equalTo(15)
make.trailingMargin.equalTo(-15)
}
- 우선 순위:
제약 조건에 우선 순위를 부여할 수 있습니다. 우선 순위는 priority 메서드를 사용하여 설정됩니다.
view.snp.makeConstraints { (make) in
make.left.equalTo(superview).priority(.high)
make.right.equalTo(superview).offset(-20).priority(.low)
}
스냅킷 쓰다가 평소에 헷갈렸던 것 기록해두기-!! ✏️
[1] translatesAutoresizingMaskIntoConstraints = false 안해도 되는지
스냅킷을 안쓰면 코드로 constraints를 잡을때,
translatesAutoresizingMaskIntoConstraints = false를 명시적으로 해줘야하잖아요..!!
https://www.raywenderlich.com/3225401-snapkit-for-ios-constraints-in-a-snap
스냅킷은 translatesAutoresizingMaskIntoConstraints = false 를 내부에서 알아서 해줍니다.
스냅킷의 LayoutConstraintItem 파일에 가보시면 있습니다.
그래서 스냅킷 쓸때는 translatesAutoresizingMaskIntoConstraints = false 안해줘도 됩니다.
[2] offset과 inset의 차이
파란색뷰를 superview(흰색뷰)에서 top, left, right, bottom 50씩 spacing 주려면 각각 어떻게 해야할까요?
1) offset을 썼을때
box.snp.makeConstraints { maker -> Void in
maker.top.equalToSuperview().offset(50)
maker.left.equalToSuperview().offset(50)
maker.right.equalToSuperview().offset(-50)
maker.bottom.equalToSuperview().offset(-50)
}
"현재 뷰 constraint = 슈퍼뷰 constraint + offset 값"
offset은 위의 공식이라고 생각하면 됩니다.
위의 수치들도 아래 공식으로 적용되어졌다고 볼 수 있어요
top = 슈퍼뷰의 top + 50
left = 슈퍼뷰의 left + 50
right = 슈퍼뷰의 right - 50
bottom = 슈퍼뷰의 bottom - 50
2) inset을 썼을때
box.snp.remakeConstraints { maker -> Void in
maker.top.left.bottom.right.equalToSuperview().inset(50)
}
insets은 UIEdgeInsets을 해줬다고 생각하면 됩니다.
저 코드는 실제 아래 코드와 똑같거든요..!
box.snp.makeConstraints { maker -> Void in
maker.top.left.bottom.right.equalToSuperview().inset(UIEdgeInsets(top: 50, left: 50, bottom: 50, right: 50))
}
하지만 저 코드는 별로 안좋은 코드에요
왜냐면 이런식으로 make와 UIEdgeInsets의 top, left,right, bottom의 순서를 다르게 쓰면 헷갈릴 수 있으니까..?!
(그래도 UIEdgeInsets의 top, left, bottom, right 순서로 먹여집니다.)
box.snp.makeConstraints { maker -> Void in
maker.top.right.bottom.left.equalToSuperview().inset(UIEdgeInsets(top: 10, left: 10, bottom: 50, right: 50))
}
그래서 저렇게 쓰고 싶으면 이렇게 사용하는 게 안헷갈리겠죠?!
box.snp.makeConstraints { maker -> Void in
maker.edges.equalTo(UIEdgeInsets(top: 10, left: 10, bottom: 50, right: 50))
}
우리의 스펙처럼 똑같은 50의 spacing값이라면 이렇게 해주는게 제일 깔끔하겠네요
box.snp.makeConstraints { (make) -> Void in
make.edges.equalToSuperview().inset(50)
}
[3] snp.left와 snp.leading의 차이 / snp.right와 snp.trailing의 차이
우선 아래 표처럼 스냅킷의 ViewAttribute는 NSLayoutAttribute와 매칭됩니다.
그럼 NSLayoutAttribute의 left와 leading, right와 trailing이 왜 각각 존재하는지 알아봐야겠죠?!
leading, trailing으로 설정하면 right-to-left 순서로 읽는 지역에서 화면이 거꾸로(flip되어서) 표시된다고 합니다.
하지만 left, right로 설정하면 안그럽니다.
(왼쪽, 오른쪽은 모든 지역에서 항상 똑같은 위치이지만(??) leading, trailing은 각 지역마다 다르게 받아들인다!!
그래서 leading, trailing으로 하면 오른쪽으로 왼쪽으로 읽는 지역에서 flip된 UI가 나온다!! 라고 생각하면 될 것 같아요)
[4] Constraint를 reference로 들고 있을 수 있는가
스냅킷을 안쓰면 이런식으로 reference 들고 있을 수 있잖아요
그리고 topSpace.constant = 100 해서 constant를 업데이트 해주고!
스냅킷도 가능하다고 합니다.
makeConstraints할때 프로퍼티에 assign해주면 됩니다.
그리고 updateOffset을 사용하면 됩니다.
근데 updateConstraints 하는게 더 스냅킷스럽고 좋아보여요-!
box.snp.makeConstraints { maker in
maker.top.bottom.left.right.equalToSuperview()
}
box.snp.updateConstraints { maker in
maker.top.equalToSuperview().offset(100)
}