근본으로 돌아가자(3)-View Layout

2024. 2. 26. 14:09·SWIFT개발일지

정말정말정말 오랜만에 글을 쓰는 것 같네요...

아카데미가 끝난 이후 개인 프로젝트도 몇 개 하고, 상하이 여행도 갔다 오고, 게임도 하고...  쫌 놀았어요 😅

 

정신줄 놓고 있었는데 한 동아리 면접을 보러 갔다가 정신을 차리게 되었습니다!

이전까지는 "나 정도면... 못하진 않지?" 했다가 그냥 탈탈 탈곡기마냥 털렸거든요... 정말정말정말 부끄러웠던 순간이었습니다...

 

그래서 다시 근본으로 돌아가자! 하고 WWDC19의 Building Custom Views with SwiftUI를 공부하게 되었습니다!

https://developer.apple.com/videos/play/wwdc2019/237/

 

Building Custom Views with SwiftUI - WWDC19 - Videos - Apple Developer

Learn how to build custom views and controls in SwiftUI with advanced composition, layout, graphics, and animation. See a demo of a high...

developer.apple.com

SwiftUI의 뷰 구조 이해하기

SwiftUI를 제대로 이해하려면 먼저 뷰의 계층 구조를 알아야 해요. 기본적인 예시로 시작해볼게요:

 

struct ContentView: View {
    var body: some View {
        Text("BLACKPINK IN YOUR AREA")
    }
}

이 코드를 보면 맨 아래 Text가 있고, body 부분과 항상 동일한 영역을 가지는 ContentView가 그 위에 있어요.

그리고 그 위에 루트뷰가 존재하죠! (Safe Area 제외 영역)

 

여기서 중요한 건 ContentView(뷰들의 최상위 Layer)는 Body 영역에 의해 결정되는 항상 layout neutral이라는 점이에요.

 

왜 이게 중요할까요? 동일하게 동작하기 때문에 레이아웃의 목적을 위해 동일한 뷰로 취급할 수 있다는 뜻이거든요!

 

레이아웃 프로세스의 3단계

 

SwiftUI의 레이아웃은 부모와 자식 간의 협상 과정이에요. 이 과정을 이해하면 SwiftUI가 훨씬 쉬워집니다:

1단계: 부모가 자식에게 크기 제안

부모뷰가 자식에게 "야, 너 이정도 크기 쓸 수 있어"라고 알려줘요.

 

2단계: 자식이 자신의 크기 결정

자식은 부모의 크기 제안을 고려해서 자신의 크기를 결정하지만, 강요는 못해요! 

🤴🏼"부모님이 나에게 300평의 땅을 주셨지만 소자 30평이면 충분합니다"

 

3단계: 부모가 자식 배치

부모는 자식의 결정을 존중한 후 자신의 좌표 공간 내에 자식을 위치시켜요.

👸🏻 "너의 뜻이 그러하니 허락하노라"

 

숨겨진 4단계: 픽셀 반올림

SwiftUI는 뷰의 모서리를 가장 가까운 픽셀로 반올림해줘요. 그래서 우리가 깔끔한 UI를 볼 수 있는 거예요! 

우리가 SwiftUI에서 자주쓰는 크기를 나타내는 모디파이어! 이것이 2번의 예입니다. 난 50 *10이면 충분해

원래라면 이렇게 안티앨리징이 존재한 상태로 보여져야하지만 SwiftUI가 알아서! 반올림해주기에 우리는 깔끔하게 볼 수 있는 이유인거죠

 

실제 레이아웃 과정을 예시로 살펴볼까요?

이제 이걸보면서 뷰의 Layout Process를 다시 공부해보자.

  1. 루트뷰가 Safe Area를 제외한 전체 공간을 제안
  2. Background Modifier는 Layout Neutral이라 Padding으로 넘어감
  3. Padding View는 자식의 각 면에 10을 더할 걸 알기에 자식에게 그만큼 적은 공간을 제안
  4. Text는 자신에게 필요한 width만큼 가져와서 Padding View에 반환
  5. Padding View는 각 면에서 자식보다 10씩 더 큰 크기를 Background에 전달이 이루어집니다

.

다른예시로 한번더 공부 ㄱㄱ.현재 이미지크기인 20, 20으로 고정된 뷰의 body size이다. 

절반정도 더 커지면 좋겠어 해서 30,30으로 frame Modifier적용해보았다. 

자 봐봐 이미지가 가지고 있는 사이즈는 커졌잖아. 근데 아보카도는 위와같이 여전히 20, 20 이다. 

Frame은 제약조건이 아니다. 액자라고 생각하면 되는 그냥 뷰이다!!

Frame은 30 30 을 주지만 이미지는 어 고마워 일단 받고 자신의 사이즈인 20,20을 사용하는 것이다. 즉 Child 자체가 자신의 크기를 선택한다는 것을 보여준다!


이렇게 Vstack이나 Hstack을 만들면 우리가 공간을 주지않아도 생기는 것을 볼 수 있다. 이는 HIG에 맞춰 Swiftui가 자동으로 해준다. 

만약 parent에게 충분한 크기를 받았다면 이렇게 자동으로 Spacer처리를 해준다.  그리고 전체의 크기를 3가지요소이기에 같은 크기만큼 배분해준다. 

하지만 이미지는 Fixed Size라고 앞에서 알려줬잖니? 그러면 어떠한 크기를 배분해주든 우리는 해당 이미지크기만큼 빼준다. 그러면 3자식중에 이미지끝났고 텍스트 두개남았지? 

빼주고 남은 영역을 반띵 해준다. 여기서 Text는 flexible size이기에 

 그러면 Delicious는 야 나 저정도 크기필요없는데? 난 이정도면 충분해~  그러면 그 Delicious가 차지하는 크기만큼 또 나머지 전체에서 빼준다. 그러면 나머지크기가 딱 Avacado Toast에게 맞는다. 

이로 인해 Text의 길이가 달라도 딱 Stack에 들어가는 구나! 만약 정확하게 공간을 3엔빵했다면 Avacado Toast는 ...이 나왔겠지요

그러면 이렇게 최종적으로 자식들의 크기가 다 정해지면 Stack은 정렬을 시작한다. 흠 정렬이 생각보다 나중에 되는 거였구나! 

 

그런데 만약 부모로부터 충분한 공간을 받지 못했어? 그러면 어떻게 쪼그라들어야 할까?

이렇게 우선순위가 높은것에 layoutPriority modifier를 붙이면 그것이 주로 나오고 나머지 dynamic한 크기를 가진놈이 줄어든다. 먼저 우선순위 제일 높은애를 배치해주고 나머지에서 사이즈를 정해주는것 같다 

Alignment

이렇게 alignment를 바텀으로 하면 해당 bounds의 밑으로 다 가는데 글씨의 크기, 이미지에따라 선이 뒤죽박죽인 모습을 볼 수 있다. 

🧑‍🎨아 미쳐버릴꺼같아요 ... 

그럴때 lastTextBaseline이라는 alignment를 하면 맨 밑을 기준으로 모두 맞춰줄수 있다. 와... 이런거 있는줄 몰랐다 맨날 leading trailiong 원툴인줄 알았던놈이 생각보다 더 대단했다. 

🧑‍🎨 이미지는 바텀라인으로부터 87.4프로만 위에 있고 나머지는 아래있으면 더 좋을꺼같아요... 부탁을 했다... 

그러면 이렇게 alignmentGuide를 이용하면 해결된다.

이 여러 스택이 섞여있는데 아 저 별들의 센터가 텍스트에 맞게 해주세요 🧑‍🎨

위와같이 alginment를 custom하면된다. 

 

추가로 Position & offset

둘이 자주 헷갈릴수 있다. 먼저 간략하게 차이점을 말하면 Offset은 layout Neutral 즉 그 밑의 컨텐츠에 똑같이 크기를 차지하여 위치를 옮기게 된다. 하지만 Position은 Parent뷰로부터 허락받은 공간을 전부 차지한다. 그래서 위치가 절대적으로 같은 위치에 위치하게 된다 .또한 position에 background를 주면 safearea무시 

'SWIFT개발일지' 카테고리의 다른 글

근본으로 돌아가자(4)-@State,@StateObject,@ObservedObject  (4) 2024.02.27
@ViewBuilder & @resultBuilder  (1) 2024.02.26
근본으로 돌아가자(2) - animation & iOS 17에서 바뀐것들  (3) 2023.12.14
View Modifier  (0) 2023.12.14
Spritekit with swiftui(1)  (1) 2023.05.01
'SWIFT개발일지' 카테고리의 다른 글
  • 근본으로 돌아가자(4)-@State,@StateObject,@ObservedObject
  • @ViewBuilder & @resultBuilder
  • 근본으로 돌아가자(2) - animation & iOS 17에서 바뀐것들
  • View Modifier
2료일
2료일
좌충우돌 모든것을 다 정리하려고 노력하는 J가 되려고 하는 세미개발자의 블로그입니다. 편하게 보고 가세요
  • 2료일
    GPT에게서 살아남기
    2료일
  • 전체
    오늘
    어제
    • 분류 전체보기 (133)
      • SWIFT개발일지 (28)
        • ARkit (1)
        • Vapor-Server with swift (3)
        • UIkit (2)
      • 알고리즘 (25)
      • Design (6)
      • iOS (42)
        • 반응형프로그래밍 (12)
      • 디자인패턴 (6)
      • CS (3)
      • 도서관 (2)
  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
2료일
근본으로 돌아가자(3)-View Layout
상단으로

티스토리툴바