Post

SwiftUI 스택과 프레임

SwiftUI 스택과 프레임

스위프트에는 버튼, 레이블, 슬라이더등 많은 뷰들이 존재한다 이 뷰들을 정렬하거나 크기를 정의하는데 사용하는 스택과 프레임을 사용한다

SwiftUI 스택

VStack(수직), HStack(수평), ZStack(중첩) 이렇게 3가지 스택 레이아웃이 있다 스택 내부에 하위 뷰들을 포함하도록 한다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import SwiftUI

struct ContentView: View {
    
    var body: some View {
        VStack {
            Text("Data")
                .font(.title)
            HStack {
                Text("Hello")
                Text("SwiftUI")
                
                VStack {
                    Image(systemName: "globe")
                        .imageScale(.large)
                        .foregroundColor(.accentColor)
                    Text("Good world!")
                }
                
                VStack {
                    Image(systemName: "person.crop.circle")
                        .imageScale(.large)
                        .foregroundColor(.accentColor)
                    Text("Hello, World!")
                }
            }
        }
        .padding()
    }
}

여기서 추가적으로 레이아웃을 정렬해야한다

 

Spacer, alignment, padding

뷰사이에 공간 추가를 위한 Spacer 컴포넌트 스택의 방향에 따라서 유연하게 확장/축소를 한다

스택의 정렬은 스택을 선얼할 때 스택에 정렬값을 지정하면 된다 VStack(alignment: .center)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import SwiftUI

struct ContentView: View {
    
    var body: some View {
        VStack(alignment: .center) {
            Text("Data")
                .font(.title)
           
            HStack(alignment: .top) {
                Text("Hello")
                Text("SwiftUI")
                Spacer()
                VStack {
                    Image(systemName: "globe")
                        .imageScale(.large)
                        .foregroundColor(.accentColor)
                    Text("Good world!")
                }
                Spacer()
                VStack(alignment: .leading, spacing: 15) { // spacing 간격 추가
                    Image(systemName: "person.crop.circle")
                        .imageScale(.large)
                        .foregroundColor(.accentColor)
                    Text("Hello, World!")
                }
            }
        }
        .padding()
    }
}

VStack 에서 사용할 수 있는 alignment

VStack은 세로로 뷰를 배치하는 스택으로, 가로 축의 정렬 옵션을 제공합니다

  • leading: 뷰를 왼쪽 정렬합니다.
  • center: 뷰를 가운데 정렬합니다. (기본 값)
  • trailing: 뷰를 오른쪽 정렬합니다.

 

HStack에서 사용할 수 있는 alignment

HStack은 가로로 뷰를 배치하는 스택으로, 세로 축의 정렬 옵션을 제공합니다

  • top: 뷰를 상단에 정렬합니다.
  • center: 뷰를 수직 중앙에 정렬합니다. (기본 값)
  • bottom: 뷰를 하단에 정렬합니다.
  • firstTextBaseline: 텍스트 뷰들의 첫 번째 텍스트 기준선을 기준으로 정렬합니다.
  • lastTextBaseline: 텍스트 뷰들의 마지막 텍스트 기준선을 기준으로 정렬합니다.

 

padding으로 간격 설정

padding(15) -> 전체 15간격

padding(.top, 10) -> 상단에만 10간격

 

뷰 그룹

여러개의 뷰를 한꺼번에 관리할려면 Group 를 사용한다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import SwiftUI

struct ContentView: View {
    
    var body: some View {
        VStack {
            Group {
                Text(" 1")
                Text(" 2")
                Text(" 3")
            }
            
            Group {
                Text(" 1")
                Text(" 2")
                Text(" 3")
            }
            . font(.largeTitle)
        }
    }
}

 

텍스트 줄 제한과 레이아웃 우선순위

HStack은 text뷰를 한줄로 보여준다

1
2
3
4
5
6
7
8
9
10
11
12
import SwiftUI

struct ContentView: View {
    
    var body: some View {
        HStack{
            Text("Hello, World1!")
            Text("Hello, World2!")
            Text("Hello, World3!")
        }
    }
}

여기서 길이를 초과하게 된다면

이렇게 자동으로 2줄로 표현된다 LineLimit()수정자를 사용시 출력 줄을 제한 할 수 있다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import SwiftUI

struct ContentView: View {
    
    var body: some View {
        HStack{
            Text("Hello, World1!")
                .lineLimit(1)//1줄만
            Text("Hello, World2!")
                .lineLimit(1...4) //1~4줄
            Text("Hello, World3!")
            Text("Hello, World4!")
        }
    }
}

여기서 우선순위를 지정한다면 layoutPriority() 해당부분의 뷰는 확실하게 보여줄 수 있다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import SwiftUI

struct ContentView: View {
    
    var body: some View {
        HStack{
            Text("Hello, World1!")
            Text("Hello, World2!")
                .layoutPriority(1) // 우선 순위
            Text("Hello, World3!")
            Text("Hello, World4!")
            Text("Hello, World5!")
            Text("Hello, World6!")
        }
    }
}

 

SwiftUI 프레임

기본적으로 뷰는 자신의 콘텐츠에 따라서 크기가 자동으로 조절된다 여기서 크기를 지정하기 위해서 frame 수정자를 이용할 수 있다

1
2
3
4
5
6
7
8
9
10
11
12
13
import SwiftUI

struct ContentView: View {
    
    var body: some View {
        Text("Hello, World!")
            .border(Color.red)
            .frame(width: 50, height: .infinity)
        Text("Hello, World!")
            .border(Color.red)
            .frame(minWidth: 10, maxWidth: 40)
    }
}

프레임은 화면을 꽉 채울때 안전영역을 준수한다 안전영역으로 카메라 노치 부분과 시간 와이파이가 있는 상단부분이 포함된다 여기에도 확장하고 싶다면 edfesIgoningSafeArea() 수정자를 사용하면 된다

 

GeometryReader

프레임의 크기는 뷰들을 담고 있는 컨테이너의 크기에 따라 조절되도록 구성할 수 있다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import SwiftUI

struct ContentView: View {
    
    var body: some View {
        GeometryReader{ geometry in
            VStack{
                Text("Hello, World!")
                    .frame(width: geometry.size.width / 2, height: (geometry.size.height / 4) * 3) // VStack의 1/2폭과 3/4높이차지
                    .border(Color.blue)
                    .padding(1)
                Text("Goodbye, World!")
                    .frame(width: geometry.size.width / 3, height: geometry.size.height / 4) //// VStack의 1/3폭과 1/4높이차지
                    .border(Color.green)
            }
            .border(Color.red)
        }
    }
}

 

스택 정렬

SwiftUI에서 HStack, VStack, ZStack 등의 스택 뷰는 정렬(alignment)을 통해 내부의 뷰들을 배치할 수 있다

1. leading

  • 왼쪽 정렬 왼쪽을 기준으로 모든 뷰가 정렬
  • 주로 HStack에서 사용하며, 왼쪽으로 모든 뷰를 정렬하고 싶을 때 사용
1
2
3
4
5
   HStack(alignment: .top) {
       Text("Hello")
       Text("SwiftUI")
   }
   .frame(maxWidth: .infinity, alignment: .leading) // 왼쪽 정렬

2. trailing

  • 오른쪽 정렬 오른쪽을 기준으로 모든 뷰가 정렬
  • 주로 HStack에서 오른쪽 정렬을 할 때 사용
1
2
3
4
5
HStack(alignment: .top) {
    Text("Hello")
    Text("SwiftUI")
}
.frame(maxWidth: .infinity, alignment: .trailing) // 오른쪽 정렬

3. center

  • 가운데 정렬 모든 뷰가 중앙에 배치
1
2
3
4
5
HStack(alignment: .center) {
    Text("Hello")
    Text("SwiftUI")
}
.frame(maxWidth: .infinity, alignment: .center) // 가운데 정렬

4. top

  • 위쪽 정렬 주로 VStack에서 사용하며, 모든 뷰를 위쪽에 정렬
1
2
3
4
5
VStack(alignment: .leading) {
    Text("Hello")
    Text("SwiftUI")
}
.frame(maxHeight: .infinity, alignment: .top) // 위쪽 정렬

5. bottom

  • 아래쪽 정렬 주로 VStack에서 사용하며, 모든 뷰를 아래쪽에 정렬
1
2
3
4
5
VStack(alignment: .leading) {
    Text("Hello")
    Text("SwiftUI")
}
.frame(maxHeight: .infinity, alignment: .bottom) // 아래쪽 정렬

6. firstTextBaseline

  • 텍스트의 첫 번째 기준선을 따라 정렬
  • 주로 HStack에서 텍스트의 첫 번째 줄을 맞춰 정렬할 때 사용
1
2
3
4
HStack(alignment: .firstTextBaseline) {
    Text("Hello")
    Text("SwiftUI")
}

7. lastTextBaseline

  • 텍스트의 마지막 기준선을 따라 정렬
  • 주로 HStack에서 텍스트의 마지막 줄을 맞춰 정렬할 때 사용
1
2
3
4
HStack(alignment: .lastTextBaseline) {
    Text("Hello")
    Text("SwiftUI")
}

8. topLeading, topTrailing, bottomLeading, bottomTrailing

  • ZStack에서 사용할 수 있는 복합적인 정렬 옵션 두 축의 정렬을 동시에 설정하여 원하는 위치에 뷰를 배치
  • 예를 들어, topLeading은 왼쪽 상단, bottomTrailing은 오른쪽 하단에 정렬
1
2
3
4
ZStack(alignment: .topLeading) {
    Color.red.frame(width: 100, height: 100)
    Text("Hello").foregroundColor(.white)
}
This post is licensed under CC BY 4.0 by the author.