UIStackView Margin 적용하기

sanghoon Ahn·2022년 2월 24일
3

Daily Issue

목록 보기
8/10
post-thumbnail

Daily Issue #8

안녕하세요 dvHuni입니다!

이번 이슈는 개발하면서 생긴 문제는 아니고,

자주 사용하지만 사용할 때 마다 다시 검색해서 찾게되는 내용이 있어서
정리 해보려고 가지고왔습니다!! 😏

스윽 지나가듯이 봐주세요 👻


무엇이 문제입니까?

위 레이아웃을 구성하려던 초보 개발자 s군은

위와 같이 컴포넌트를 나누기로 했고, UIStackView를 사용하여 만들기로 결심합니다. ㅎ

이유는, 아래쪽 영역에 계속해서 메뉴가 추가/삭제 될 것으로 예상되기 때문에 추가/삭제가 간편한 UIStackView를 사용하려고 했다고 합니다. 😄

(컬렉션뷰로 해도 됩니다.. 그냥 억지좀 부릴게요.. 🙏)

상단의 NavigationBar는 이미 만들어져 있다고 생각하고, 선택된 영역만 만든다고 가정할게요!

이때 상, 좌, 우 에 동일한 여백이 들어가죠?

“UIStackView의 Layout을 잡을 때, 여백을 줘도 되지만, UIStackView 자체에 ContentInset을 줘도 되지 않을까?”

라는 생각이 들지않으세요?????? 아니에요???? 아니라구요??? 🤔  그럴수있죠

진짜 억지이긴한데.. 제가 글을 써야하니 넘어가주세요 ... ㅠ

어쨌든 !! 오늘의 이슈는 요겁니다 !! UIStackView에 Margin 적용하기!!

뭐 이런걸.. 이슈로 가져왔어.. UIStackView에 뭐 conetntInset Property 설정하면 되는거아냐??

라고 생각한 당신!!! 👶  과 나 자신

당당하게 코드를 써보지만 나오지않는다...

왜냐하면 contentInset은 UIScrollView에 있는 Property이기 때문!!

그렇다면 UIStackView에는 어떻게 적용해야 하나용 🐉 ??

바로 layoutMargins Property를 이용합니다!

layoutMargins는 view에 content를 위치시킬때, 적용하는 spacing입니다.

또, UIEdgeInsets Type이니까 손쉽게 원하는 부분의 여백을 지정할 수 있습니다.

stackView.layoutMargins = UIEdgeInsets(top: 10, left: 10, bottom: .zero, right: 10)

하지만 이!대!로! 실행하면 원하는데로 여백이 지정되지 않습니다!

왜냐하면, UIStackView의 isLayoutMarginsRelativeArrangement Property 때문입니다.

@available(iOS 9.0, *)
open class UIStackView : UIView {
	...
	...
	/* Uses margin layout attributes for edge constraints where applicable.
	        Defaults to NO.
	*/
	open var isLayoutMarginsRelativeArrangement: Bool
}

UIStackView의 Definition을 보시면, isLayoutMarginsRelativeArrangement 이라는 Property가 있는데,

조금 더 자세하게 알기 위해 Documentation을 보면!!!!

해당 Property는 UIStackView가 arranged view를 위치 시킬때, layout margin을 사용할지 안할지 결정하는 값이라고 합니다!

또, 기본값이 false이기 때문에 위에서 지정한 layoutMargins를 무시하게 되는겁니다.

그래서 우리는 이전의 코드에서 한줄을 더 추가해야합니다.

stackView.layoutMargins = UIEdgeInsets(top: 10, left: 10, bottom: .zero, right: 10)
stackView.isLayoutMarginsRelativeArrangement = true

짠-!

참, layoutMargins는 UIView의 Property이고, isLayoutMarginsRelativeArrangement은 UIStackView의 Property입니다.

UIStackView만 특별한 경우라고 생각해주시면 되요!

이 Property가 왜 UIStackView에만 존재할까요..? 🤔 아돈노...
(정답을 알려줘)

하하ㅎㅎㅎㅎ.ㅎㅎ핳 정말 간단하죠..?? 코드 두줄이라니...

근데 이걸 잘 모르고 있으면 계속.. contentInset만 생각나더라구요...

UIScrollView에서는 자주써서 그런가?

여기서 끝나면 너무 날먹인것 같으니까😅
추가로 알고있으면 좋은 내용도 휘리릭 알려드리고 물러가겠습니다.

위에서 구성한 레이아웃 에서 보안 의 아래쪽에는 8의 여백, PIN 변경 메뉴에는 4의 여백을 주어야 할때

UIStackView에서는 간단하게 여백을 추가할 수 있습니다.

바로, setCustomSpacing(_:after:)메소드를 사용하면 됩니다.

코드로 보면,

let stackView = UIStackView()
let security = UIView() // 보안 레이블을 가지고 있는 뷰
let pinMenu = Menu(title:"보안", type: .navigate)
let authMenu = Menu(title:"TouchID/ FaceID 사용", type: .switch)

stackView.addArrangeSubview(security)
stackView.addArrangeSubview(pinMenu)
stackView.addArrangeSubview(authMenu)

// 여백 설정하기
stackView.setCustomSpacing(8, security) // 보안 메뉴 아래에 8의 여백
stackView.setCustomSpacing(4, pinMenu)  // TouchID/ FaceID 사용 메뉴 아래에 4의 여백

짠~

이미 알고계셨던 분들은 귀엽게 보고 넘어가주세 YO -!

(저는 8이나 4의 height를 가진 UIView를 만들어서 넣곤 했답니다 ^0^)


오늘은 너무 간단한 내용이니까 빠르게 지나가볼게요 .. 🥲

안뇽 🖐


지적이나 질문은 저에게 큰 도움이 됩니다 🤓

오늘도 읽어주셔서 감사합니다 🙇🏻‍♂️

profile
hello, iOS

4개의 댓글

comment-user-thumbnail
2022년 11월 4일

감사합니다.

답글 달기
comment-user-thumbnail
2023년 4월 10일

감사합니다 ㅠㅠㅠ

답글 달기
comment-user-thumbnail
2023년 12월 3일

안녕하세요 지나가는 뉴비인데요 혹시 잘 아실듯 해서 여기에 문의를 드려요. 지금 UIStackView를 써서 .vertical로 작업을 하고 있는데 컴퍼넌트 마다 여백을 다르게 주고 싶어요. 예를들면 titleTextField, ImageContainer가 있을 때 titleTextView는 좌우 20px 를, ImageContainer는 0px을 주려고 해요.

구글링해서 NSLayoutConstraint.active([ ... ]) 에 titleTextView.leadingAnchor.constrain(equalTo. view.leaidngAnchor, constant: 20), ... ,ImageContainer ... (equalTo: view.leadingAnchor, constant: 0) 이런식으로 명령어를 넣으면 구현은 되는데 워닝들이 좌르륵 뜨네요 ㅜㅜ 뜬금없는 장문의 질문이라 좀 민망하네요...ㅜㅜ 좋은 하루 되시어요~ :)

1개의 답글