개발린생

Compose와 SwiftUI 기본 구조 - 레이아웃 시스템 본문

Dev Lab ✧.·˚/Android & iOS

Compose와 SwiftUI 기본 구조 - 레이아웃 시스템

김블루 2024. 10. 25. 15:00

이전 포스팅에 이어 Compose와 SwiftUI 레이아웃 시스템에 대해 공부한 내용을 적어보려한다.

Compose, SwiftUI 모두 뷰를 수직, 수평 방향이나 위로 쌓을 수 있는 레이아웃 시스템을 제공한다.


Android Compose의 레이아웃 시스템 Column, Row, Box

  • Column, Row, Box 레이아웃 컴포저블을 사용해 UI 요소를 배치한다.
  • Column은 수직 방향(⬇️), Row는 수평 방향(➡️), Box는 겹쳐서 배치할 수 있는 레이아웃을 제공한다.

Column 예시 코드:

// VStack과 유사한 레이아웃 컴포저블 Column 예제 함수
@Composable
fun ColumnExample() {
    Column(
        modifier = Modifier
            .fillMaxWidth() // 가로로 꽉 차게
            .background(Color.LightGray) // 배경 색
            .padding(8.dp), // 내부 패딩
        verticalArrangement = Arrangement.spacedBy(4.dp), // 아이템 간의 간격을 8dp로 설정
        horizontalAlignment = Alignment.CenterHorizontally // 아이템을 수평으로 중앙 정렬
    ) {
        Text("Item 1")
        Text("Item 2")
        Text("Item 3")
    }
}

 

 

Row 예시 코드:

// HStack과 유사한 레이아웃 컴포저블 Row 예제 함수 1
@Composable
fun Row1Example() {
    Row(
        modifier = Modifier
            .fillMaxWidth() // 가로로 꽉 차게
            .background(Color.LightGray) // 배경 색
            .padding(8.dp), // 내부 패딩
        horizontalArrangement = Arrangement.SpaceBetween, // 아이템 사이에 고르게 간격을 주고 양쪽 끝으로 배치
        verticalAlignment = Alignment.CenterVertically // 아이템을 수직으로 중앙 정렬
    ) {
        Text("Left")
        Text("Center")
        Text("Right")
    }
}

 

 

Box 예시 코드:

// ZStack과 유사한 레이아웃 컴포저블 Box 예제 함수 1
@Composable
fun Box1Example() {
    Box(
        modifier = Modifier
            .size(150.dp) // 크기
            .background(Color.LightGray), // 배경 색
        contentAlignment = Alignment.Center // Box 내에서 아이템을 중앙 정렬
    ) {
        // 원형 박스
        Box(
            modifier = Modifier
                .size(50.dp)
                .background(Color.Blue, CircleShape)
        )
        // 텍스트
        Text(
            text = "Centered",
            color = Color.White
        )
    }
}

 

Compose 레이아웃 시스템


iOS SwiftUI의 레이아웃 시스템 VStack, HStack, ZStack

  • VStack, HStack, ZStack을 사용해 요소를 배치한다.
  • VStack은 수직 방향(⬇️), HStack은 수평 방향(➡️), ZStack은 겹쳐서 배치할 수 있는 레이아웃을 제공한다.

VStack의 "V"는 Vertical, HStack의 "H"는 Horizontal 이다.

ZStack의 "Z"는 특정 단어를 줄인 것이 아닌, 3D 좌표계에서 Z축을 나타내는 기호에서 유래된 것이다. (Z축은 깊이)

즉, Z축은 화면의 앞과 뒤, 요소들이 겹쳐지는 방향을 의미한다. (뷰들이 Z축 상에서 화면의 깊이 방향으로 쌓이는 스택을 말함)

 

VStack 예시 코드:

// Column과 유사한 VStack 레이아웃 컴포넌트
struct VStackExample: View {
    var body: some View {
        VStack(
            alignment: .center, // 수평 중앙 정렬
            spacing: 4 // 각 아이템 간의 간격
        ) {
            Text("Item 1")
            Text("Item 2")
            Text("Item 3")
        }
        .frame(maxWidth: .infinity) // 가로로 꽉 차게
        .padding(8) // 내부 패딩
        .background(Color.gray.opacity(0.3)) // 배경 색상
    }
}

 

 

HStack 예시 코드:

// Row와 유사한 HStack 레이아웃 컴포넌트 1
struct HStackExample1: View {
    var body: some View {
        HStack(
            spacing: 4 // 각 아이템 간의 간격
        ) {
            Text("Left")
            Spacer() // 공간을 나눠서 양쪽 끝으로 배치
            Text("Center")
            Spacer()
            Text("Right")
        }
        .frame(maxWidth: .infinity) // 가로로 꽉 차게
        .padding(16) // 내부 패딩
        .background(Color.gray.opacity(0.3)) // 배경 색상
    }
}

 

 

ZStack 예시 코드:

// Box와 유사한 ZStack 레이아웃 컴포넌트 1
struct ZStackExample1: View {
    var body: some View {
        ZStack(
            alignment: .center // ZStack 내부 아이템을 중앙 정렬
        ) {
            // 원형 박스
            Circle()
                .fill(Color.blue) // 색상
                .frame(width: 50, height: 50) // 크기
            
            // 텍스트
            Text("Centered")
                .foregroundColor(.white) // 텍스트 색상
        }
        .frame(width: 150, height: 150) // ZStack 크기
        .background(Color.gray.opacity(0.3)) // 배경 색상
    }
}

SwiftUI 레이아웃 시스템

 

 


간단하게 구현해본 뷰를 보고 발견한 이슈

Compose, SwiftUI 모두 여러 뷰가 겹쳐서 쌓이는 레이아웃을 상단 좌측 정렬로 구현했다.

컴포즈의 Box는 내부 아이템을 내가 원하는대로 Box 크기 내에서 정렬이 되었지만, 스유는 텍스트가 위로가고 원형이 왼쪽으로 배치된 느낌은 들지만 내가 원했단 상단 좌측 정렬로 적용되지 않았다.

 

가볍게 서치해보니 ZStack은 내부 아이템 중 가장 큰 아이템을 기준으로 내부 사이즈를 정한다고 한다.

ZStack에도 크기를 지정해뒀기 때문에 왜 내부 사이즈를 가장 큰 아이템 기준으로 맞추는지, 찾아본 정보가 맞는지 의문이다.

SwiftUI가 그렇다면 그런거지만,, 다른 원인이 있을수도 있겠다는 생각이 들고, 그럼 ZStack 사이즈에 맞게 정렬이 되길 원하면 내부 아이템 중 하나를 가장 큰 사이즈로 적용해야하나...?

이 부분은 ZStack을 별도로 자세히 다뤄봐야겠다.

 

 

Compose Box와 SwiftUI ZStack 상단 좌측 정렬

 

 


💬 다음 공부는

다음은 긴 목록이나 스크롤 가능한 리스트를 구현케하는 Android Compose의 LazyColumn, LazyRow와 iOS SwiftUI의 List 예제를 작성해보고 공부할 예정이다.


🔗  GitHub Repository

Compose Components : https://github.com/blueland99/ComposeComponents

SwiftUI Components : https://github.com/blueland99/SwiftUIComponents

 

위에서 작성한 코드와 그 외 예제 코드를 작성해둠