안녕하세요 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^)
오늘은 너무 간단한 내용이니까 빠르게 지나가볼게요 .. 🥲
안뇽 🖐
지적이나 질문은 저에게 큰 도움이 됩니다 🤓
오늘도 읽어주셔서 감사합니다 🙇🏻♂️
안녕하세요 지나가는 뉴비인데요 혹시 잘 아실듯 해서 여기에 문의를 드려요. 지금 UIStackView를 써서 .vertical로 작업을 하고 있는데 컴퍼넌트 마다 여백을 다르게 주고 싶어요. 예를들면 titleTextField, ImageContainer가 있을 때 titleTextView는 좌우 20px 를, ImageContainer는 0px을 주려고 해요.
구글링해서 NSLayoutConstraint.active([ ... ]) 에 titleTextView.leadingAnchor.constrain(equalTo. view.leaidngAnchor, constant: 20), ... ,ImageContainer ... (equalTo: view.leadingAnchor, constant: 0) 이런식으로 명령어를 넣으면 구현은 되는데 워닝들이 좌르륵 뜨네요 ㅜㅜ 뜬금없는 장문의 질문이라 좀 민망하네요...ㅜㅜ 좋은 하루 되시어요~ :)
감사합니다.