궁금한 내용을 검색해보세요!
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
서근 개발노트
티스토리에 팔로잉
SWIFTUI/View layout

SwiftUI : View layout (HStack / VStack / ZStack)

서근
QUOTE THE DAY

-
Written by SeogunSEOGUN

반응형

 

view layout에 대한 전반적인 내용을 간단히 살펴보겠습니다. 세부적인 내용은 다음 게시글에서 다루도록 하겠습니다.

View Layout 

Stack

Stack은 SwiftUI에서 뷰를 배치하는 데 사용하는 컨테이너 뷰로, 콘텐츠로 전달된 지식 뷰들을 어떤 형태로 배치할 것인지 결정짓습니다. SwiftUI에서는 거의 필수적으로 활용되므로 매우 중요하며 사용 방법 또한 매우 간단합니다.

 

Stack에는 가로방향 HStack, 세로방향 VStack, 겹겹히 쌓아있는 ZStack 총 세 가지 종류가 있습니다.

var body: soom View {
   Text("hello")  //컴파일 오류
   Text("SwiftUI")
}

var body: soom View {
 VStack {
   Text("hello")
   Text("SwiftUI")
 }
}

라이브러리에서 보이는 아이콘에서도 각 스택이 어떤 역할을 하는지 알아볼 수 있습니다.

 

각 스택이 어떻게 사용되는지 알아보기 위해 2개의 사각형을 만들어 결과를 확인해 보겠습니다.

HStack {    //이 부분만 HStack, VStack, ZStack으로 수정해 봅니다.
 Rectangle()
    .fill(Color.green)
    .frame(width: 150, height: 150)
  Rectangle()
    .fill(Color.yellow)
    .frame(width: 150, height: 150)     
 }

ZStack이 정말 초록색 사각형이 노란색 사각형에 가려진 것이 맞는 것인지 확인하고자, 노란색 사각형에 위치를 이동시키는 수식어 offset 수식어를 적용해봅니다.

ZStack {
 ...
 Rectangle()
    .fill(Color.green)
    .frame(width: 150, height: 150)
    .offset(x: 40, y:40)  //각각 x축과 y축으로 40씩 이동
 }

다시 정리해보면, H / V / Z 스택의 레이아웃은 다음 그림과 같은 모습으로 나타납니다.

생성자

Stack에 대한 생성자를 살펴보면,

뷰의 정렬을 위한 alignment

뷰간의 간격을 지정하는 spacing

스택에서 콘텐츠로 표시할 content

이렇게 3개의 매개 변수를 받고 있습니다. 매개 변수를 지정해주지 않으면 '기본값'으로 지정됩니다.

Alignment

alignment 매개 변수는 각 스택마다 서로 다른 타입을 받아들입니다.

 

예를 들어,

HStack은 가로 방향이므로 배열하기에 세로 방향에 대한 정렬 값인 VerticalAlignment타입이 필요.

VStack은 세로 방향이므로 배열하기에 가로 방향에 대한 정렬값은 HorizontalAlignment가 필요.

ZStack은 가로와 세로축에 대한 정보가 모두 필요하기 때문에 두 가지 값을 가진 Alignment가 필요.

 

VerticalAlignment 종류 (HStack)

  • top / bottom / center

HorizontalAlignment 종류 (VStack)

  • leading(왼쪽) / center / trailing(오른쪽)

Alignment 종류 (ZStack)

  • toptrailing(오위) / bottomtrailing(오아) / topleading(왼위) / bottomleading(왼아)
HStack(alignment:.top/center/bottom) {
         Rectangle()
            .fill(Color.green)
            .frame(width: 100, height: 100)
            Rectangle()
                .fill(Color.red)
                .frame(width: 150, height: 500)
 }

Spacing

다음 코드처럼 spacing의 값을 명시적으로 지정해주면 원하는 간격만큼 떨어지게 하는 효과를 줄 수 있습니다.

HStack(spacing: 0) { ... }
HStack(spacing: 50) { ... }
HStack(spacing: 50) {
  Rectangle()
      .fill(Color.green)
      .frame(width:
      .fill(Color.red)
      .frame(width: 
}

사용

위에 배운 내용을 바탕으로 화면을 그려보겠습니다. 아래 코드를 확인하며 어떤 식으로 구성되는지 파악하시면 좋습니다. :)

HStack 

VStack {
           // HStack 타이틀
            HStack {
                Text("HStack").font(.title)
                Spacer() }
            
            // HStack 도형 정렬
            HStack(alignment: .bottom,spacing: 20) {
                RoundedRectangle(cornerRadius: 20)
                    .foregroundColor(.blue)
                    .frame(width: 100, height: 100)
                
                RoundedRectangle(cornerRadius: 20)
                    .foregroundColor(.red)
                    .frame(width: 100, height: 150)
                
                RoundedRectangle(cornerRadius: 20)
                    .frame(width: 100, height: 200)
                    .foregroundColor(.yellow)
            }
}

여기서 ZStack을 활용해 HStack의 도형 뒤쪽에 얇은 선 하나를 추가해보겠습니다. 

VStack {
           // HStack 도형 뒤쪽 선 추가
            ZStack {
                Rectangle().frame(height: 10).padding(.top, 100)
                // HStack 도형 정렬
                HStack(alignment: .bottom,spacing: 20) {
                    
                   ...
                   
                }
            }
}

VStack

VStack {
             HStack {
                 Text("VStack").font(.title)
                 Spacer() }
             
             // VStack 도형 정렬
            VStack(spacing: 10) {
                 RoundedRectangle(cornerRadius: 20)
                     .foregroundColor(.blue)
                 RoundedRectangle(cornerRadius: 20)
                     .foregroundColor(.red)
                 RoundedRectangle(cornerRadius: 20)
             }
            .frame(width: 100, height: 100)
}

ZStack

VStack {
            // ZStack 도형 정렬
            ZStack {
                RoundedRectangle(cornerRadius: 20)
                    .foregroundColor(.blue)
                    .frame(width: 200, height: 200)
                
                RoundedRectangle(cornerRadius: 20)
                    .foregroundColor(.red)
                    .frame(width:150, height: 150)
                
                RoundedRectangle(cornerRadius: 20)
                    .frame(width: 100, height: 100)
                    .foregroundColor(.yellow)
            }
}

전체 코드

<hide/>

import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
           // HStack 타이틀
            HStack {
                Text("HStack").font(.title)
                Spacer() }
            
           // HStack 도형 뒤쪽 선 추가
            ZStack {
                Rectangle().frame(height: 10).padding(.top, 100)
                // HStack 도형 정렬
                HStack(alignment: .bottom,spacing: 20) {
                    
                    RoundedRectangle(cornerRadius: 20)
                        .foregroundColor(.blue)
                        .frame(width: 100, height: 100)
                    
                    RoundedRectangle(cornerRadius: 20)
                        .foregroundColor(.red)
                        .frame(width: 100, height: 150)
                    
                    RoundedRectangle(cornerRadius: 20)
                        .frame(width: 100, height: 200)
                        .foregroundColor(.yellow)
                }
            }
            
            // 구분선 추가
            Divider()
                .background(Color.blue)
                .padding([.top, .bottom],20)
            
            // VStack 타이틀
             HStack {
                 Text("VStack").font(.title)
                 Spacer() }
             
             // VStack 도형 정렬
            VStack(spacing: 10) {
                 RoundedRectangle(cornerRadius: 20)
                     .foregroundColor(.blue)
                 RoundedRectangle(cornerRadius: 20)
                     .foregroundColor(.red)
                 RoundedRectangle(cornerRadius: 20)
             }
            .frame(width: 100, height: 100)
             
             // 구분선 추가
             Divider()
                 .background(Color.blue)
                 .padding([.top, .bottom],20)
            
            // ZStack 타이틀
            HStack {
                Text("ZStack").font(.title)
                Spacer()
            }
            
            // ZStack 도형 정렬
            ZStack {
                RoundedRectangle(cornerRadius: 20)
                    .foregroundColor(.blue)
                    .frame(width: 200, height: 200)
                
                RoundedRectangle(cornerRadius: 20)
                    .foregroundColor(.red)
                    .frame(width:150, height: 150)
                
                RoundedRectangle(cornerRadius: 20)
                    .frame(width: 100, height: 100)
                    .foregroundColor(.yellow)
            }
        }
        //VStack 패딩 조절
        .padding()
    }
}

 

 

읽어주셔서 감사합니다🤟

 

 

 


잘못된 내용이 있으면 언제든 피드백 부탁드립니다.


서근


위처럼 이미지 와 함께 댓글을 작성할 수 있습니다.