XLOG

[UIKit] Autolayout 이해하기 본문

Swift/UIKit

[UIKit] Autolayout 이해하기

X_PROFIT 2023. 3. 9. 16:53

1. 배경

 

많은 취업 공고에 Autolayout 에 대한 이해를 기본 자격요건으로 적혀있는 경우가 많다.

Autolayout 이 왜 중요할까? 이유는 간단한 것 같다. 2010년 이전엔 대부분이 비슷한 크기, 비슷한 비율의 모니터로 인터넷을 사용했다.

하지만 2010대에 다양한 핸드폰, 태블릿... IT 서비스를 즐길 수 있는 다양한 기기가 나왔으며, 그만큼 사이즈 또한 다양해졌다. 가로모드까지....

 

UIKit 의 경우 이전 포스팅에서도 얘기를 했었지만, 명시형 프로그래밍 언어이다. View 를 명시하고 추가할때, 사이즈도 추가를 해줘야 한다.

위에 사진을 보게 되면, 사이즈를 정한 View의 경우 시뮬레이터 상에서 우리가 확인할 수 있지만, 사이즈를 지정해주지 않은 View는 눈에 보이진 않는다. 하지만 뷰계층에선 두개의 라벨뷰가 추가되어 있는 것을 볼 수 있다.

즉 뷰의 사이즈와 포지션이 있어야 window 에서 view 를 확인할 수 있다. 하지만 여기서 하나의 디바이스에 맞게 크기를 결정하게 되면 큰 문제가 발생한다. 예를 들면 아이폰 가로 사이즈에 이미지 크기를 정했다면, 아이패드에선 화면의 여백이 많이 생기고 한쪽에 쏠려 있어 보일 것이다. 반대로 아이폰 미니로 가면 이미지가 짤려보일 수 있을 것 이다. 즉 화면의 사이즈별로 상대적으로 설정해 줄 필요가 있는 것 이다.

 

방법이 없는 것은아니다. 어떤 디바이스에서 실행했는지를 확인하여 거기에 맞는 사이즈 크기를 각각 정해줄 수 있다. 반응형 웹을 공부할 때 그런 방식을 사용했었다.

반응형 웹에선 사이즈에 따라 css 값을 설정해주는 것을 확인할 수 있다. (요즘은 잘 모릅니다....)

하지만 이건 임시적이라고 생각한다. 아이폰, 아이패드, 맥북 시대가 달라지고(트렌드) 기술력의 발전으로 베젤도 좁아지고 하면서 화면 크기가 달라진다. 그렇다면 유지보수를 할 때 새로운 사이즈가 나올때마다 우리가 만든 서비스 관리가 필요하게 된다. 또한 코드 또한 길어진다. 이런 것을 보완하기 위해 나오 아이디어 갔다.

 

2. Autolayout 이란?

 

그렇다면 Autolayout 이란 무엇일까?

 

출처 : https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/index.html#//apple_ref/doc/uid/TP40010853-CH7-SW1

간단하게 constraints 를 통해 뷰를 위치시키는 방법이다. constraints 는 제약조건이다. 즉 크기와 위치를 계산할 수 있도록 조건을 주는 것이다. 뷰의 사이즈를 정해주는 것이 아닌, 기준으로 부터 어느 위치에 놓아라 라고 명시를 해주는 것 이다.

 

방법으론 각 뷰에 어떤 기준과의 4개의 조건(top, leading, trailing, bottom) 을 줌으로 viewController의 view 와의 간격을 주면서 계산을 하는 것이다. 

leading 과 left 의 차이는, leading 은 해당 국가의 우선으로 계산된다. 예로 우리나라는 글씨를 왼쪽부터 읽기 때문에, left 와 같게 작용을 하지만 오른쪽부터 읽는 나라에선 right 로 작동한다.

 

3. 주의해야할 점

 

이런만 보면 굉장히 간단해 보인다. 하지만 여기서 주의해야 할 점이 있다. 만약 위에 화면에서 bottom의 대한 제약조건을 주지 않았다면?

우리 앱은 저 뷰의 높이를 계산할 수 없게된다. 이럴 경우 height 에 관한 조건을 주어야 한다. 이 처럼 width, height 을 추론할 수 있게 조건을 주어야 한다. 또한 subview 들끼리 조건을 줄 수 있다. 코드로 짜게 된다고 하면 그 제약조건을 활성화 해주는 시기가 있다. 

NSLayoutConstraint.activate([
    imageCarouselCollectionView.topAnchor.constraint(equalTo: topAnchor, constant: 16),
    imageCarouselCollectionView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
    imageCarouselCollectionView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
    imageCarouselCollectionView.heightAnchor.constraint(equalToConstant: height),

])

NSLayoutConstraint.activate([
    pageControl.centerXAnchor.constraint(equalTo: centerXAnchor),
    pageControl.bottomAnchor.constraint(equalTo: imageCarouselCollectionView.bottomAnchor, constant: -16)
])

위에 코드에선 pageControl 의 bottomAnchor 는 기준을 imageCarouselCollectionView.bottomAnchor 로 결정했다. 하지만 만약 윗줄에서 imageCarouselCollectionView 의 제약조건을 주지 않았다면 우리의 앱은 pageControl 의 위치, 크기를 계산할 수 없다. 아무리 코딩을 정확하게 하였어도 순서가 섞이게 되면 제약조건에 충돌이 생긴다는 것이다. 

컴퓨터도 우리랑 똑같다. 이건 마치 친구(내 생일을 모르는 친구)와 약속을 잡을 때, 약속 날짜를 명확하게 말하지 않고 내 생일날 만나자 라고 말하는 것과 같은 것이다.

 

이렇게 제약조건의 중복, 그로 인해서 충돌이 발생하는지 발생하지는 않는지, 기준이 명확한지 생각을 해야한다.

 

또한 제약조건을 바꾸고 싶다면 기존 조건을 deactive 후에 새로운 조건을 active를 해줘야 한다. 그리고 view layout 을 업데이트 해주는 함수인 layoutIfNeeded() 를 해줘야 한다. 앞서 얘기한 이유와 동일하다. 이미 뷰는 내가 이전에 한 제약조건을 작동 시켰다. 새로운 조건을 주게 되면 결국 조건의 충돌이 발생하게 된다. 그렇기에 바꾸고 바뀌었다고 말해주는 것이다.

 

4. 쉽게 사용하는 방법은?

 

그건 바로 StackView 이다. 기본적인 UIView를 제외하고, UILabel, TextView, PrgoressBar 등은 그 안에 들어간 컨텐츠에 따라 컨튼츠가 선호하는 크기를 가지고 있다. 이러한 View 를 StackView 에 넣게 되면 StackView의 설정에 따라 고유한 크기를 적절히 조정하여 LayOut을 잡아준다.

위에 사진을 보면 StackView에 담게 되면 StackView 내부 subView의 경우는 StackView 사이즈에 맞게 알아서 조절이 된다. 즉 우리는 감싸고 있는 StackView의 제약조건만 주게되면 된다. 또한 StackView 자체를 다른 StackView의 SubView로 추가할 수 있다.

wwdc15 Mysteries of Auto Layout 에서도 StackView의 장점을 잘 얘기해 준다.

 

5. 결론

 

이처럼 AutoLayout 결국 다양한 기기를 가지고 있는 많은 사람들이게 효율적인 방법으로 앱의 화면을 보여주는 힘을 가지고 있다.

이전에 포스팅한 좋은 앱과 관련된 글에서도 언급한 것처럼 앱의 유저와의 인터렉션은 앱이 가지고 있는 정보만큼 중요하다. 그렇기에 앱이 보여지는 화면의 통일성, 정렬 등이 주는 느낌도 매우 중요하다. 

 

또한 이렇게 layout 과 관련된 것을 공부하다보니 intrinsicContentSize 에 대한 언급으로 뷰가 선호하는 사이즈에 대한 값을 가지고 있다는 것을 알 수 있다. 이러한 것으로 CollectionView(TableView) 의 동적셀의 사이즈를 결정하기 위한 힌트를 얻어간다. 

그리고 예전에 킨디 프로젝트를 진행하며 포스팅, 댓글이 들어간 뷰에 대해 고민할때 무작정 CollectionView 를 활용하여 View를 렌더한다는 생각만 했었는데, 댓글파트에 StackView를 활용한다면 댓글 하나의 StackView를 SubView로 사용하여  댓글마다 고유 크기를 고려하지 않고도 쉽게 구현할 수 있다란 생각이 든다. Collectionview의 동적 높이를 고민하지 않고도.....

이 얘기는 AutoLayout의 활용으로 개발 기간을 단축 시킬 수 있다는 얘기이지 않은가....