인프런 커뮤니티 질문&답변

(알 수 없음)님의 프로필 이미지

작성한 질문수

Part1: 진짜 왕초보 iOS 배우기(SwiftUI, SwiftData, 2024)

VStack, HStack으로 뷰 구성하기 강의 padding 질문입니다

해결된 질문

24.09.12 17:59 작성

·

69

·

수정됨

1

안녕하세요 강의 수강 중 이해가 안되는 부분이 있어서 질문 드립니다

 

import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack{
            HStack{
                Image("dogProfile")
                    .resizable()
                    .frame(width: 120, height: 120)
                    .clipShape(Circle())
                    .overlay(
                        Circle()
                            .stroke(Color.teal, lineWidth: 3)
                    )
                VStack(alignment: .leading){
                    Text("이름: 키도")
                    Text("시바견")
                    Text("2017년 5월생")
                }
                // VStack 안에 있는 뷰에 모디파어어를 일괄 적용하고 싶을 경우 이런 식으로 구성할 수 있다(일괄 적용이라는 표현보단 Vstack 자체에 모디파이어를 적용했다는 표현이 더 옳을지도?
                .font(.system(size: 20)) // 정보 글의 폰트 사이즈
                .padding(.leading, 20) // 그림과 정보 글 사이의 공백
            }
            .padding(.bottom, 20)
            
            VStack(alignment: .leading, spacing: 10){
                Text("좋아하는 것")
                    .font(.system(size: 20))
                    .bold()
                Divider() // 좋아하는 것 밑에 있는 선을 그려주는 함수
                Text("- 각종 고기(🐮 = 🐷 = 🐔 > 🐟)")
                Text("- 장본 게  담겨 있는 종량제 봉투")
                Text("- 집에 새로 온 사람")
            }
            .padding()
            .background(
                RoundedRectangle(cornerRadius: 15)
                    .fill(.mint)
                    .opacity(0.2) // 색의 투명도를 지정하는 모디파이어 0이면 완전 투명
                    .shadow(radius: 5)
            )
            
            VStack(alignment: .leading, spacing: 10){
                Text("스킬")
                    .font(.system(size: 20))
                    .bold()
                Divider() // 좋아하는 것 밑에 있는 선을 그려주는 함수
                HStack(alignment: .top, spacing: 30){
                    VStack(alignment: .leading, spacing: 10){
                        Text("- 앉아")
                        Text("- 엎드려(앉아와 자주 혼동함)")
                        Text("- 하우스(집으로 들어가기)")
                    }
                    VStack(alignment: .leading, spacing: 10){
                        Text("- 손")
                        Text("- 코")
                    }
                }
            }
            .padding()
            .background(
                RoundedRectangle(cornerRadius: 15)
                    .fill(.pink)
                    .opacity(0.2) // 색의 투명도를 지정하는 모디파이어 0이면 완전 투명
                    .shadow(radius: 5)
            )
        }
        .padding() // 질문인 부분
    }
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }
}

위 코드 맨 마지막 padding을 보면 가장 처음 사용하는 VStack에 .padding을 적용하는 코드입니다 궁금한 건 저 padding의 값을 50, 100 이렇게 설정해도 Vstack의 위 아래 여백은 변하지 않는다는 점입니다. 분명 .padding에 값을 넣어주지 않으면 기본적으로 상하좌우 모든 부분에 여백을 주는 걸로 알고 있는데 만 상하 부분의 여백이 변하지 않는 것을 확인했습니다.

 

개인적으로 여백을 넓게 잡으면 여백을 잡기 위해 글자나 사진 사이즈 등이 뭉개지는 현상이 발생할 줄 알았는데 좌우는 뭉개지는 데 상하는 뭉개지지 않더라구요 Vstack이 기본적으로 가지고 있는 공간이 있는 최소한의 건지... 혹시 뭉개지지 않는 이유를 알 수 있을까요??

 

그리고 혹시 // VStack 안에 있는 뷰에 모디파어어를 일괄 적용하고 싶을 경우 이런 식으로 구성할 수 있다(일괄 적용이라는 표현보단 Vstack 자체에 모디파이어를 적용했다는 표현이 더 옳을지도? 이 주석 제가 맞게 이해한 건지도 알려주시면 정말 감사하겠습니다..!

 

좋은 하루 보내세요! 감사합니다!

답변 1

0

애구마(agmma)님의 프로필 이미지
애구마(agmma)
지식공유자

2024. 09. 14. 14:50

안녕하세요!

.padding부분은 위아래에 다른 뷰가 없어서 패딩을 주나 안주나 똑같이 보이는것입니다. 위아래에 다른 뷰가 있다면 간격이 늘어날거에요

현재 제일 상위의 있는 VStack의 뷰가 전체를 차지하고 있는게 아니라 사진만큼의 공간을 차지하고 있습니다.

image.png

초록색이 VStack의 영역

빨간색이 패딩으로 늘어난 영역입니다.

질문해주신 padding() 위아래로 아래 코드를 한번 입력해보세요~

.background(.green)
.padding()
.background(.pink)

 

그리고 두번째 VSTack안에 있는 뷰에 모디파이어... 이부분은

질문자님이 생각하시는게 맞습니다!

모디파이어에 따라 내부 뷰 각각에 적용되는게 있고, 컨테이너 뷰전체에 적용되는게 있는거 같아요

즐거운 추석되세요~

(알 수 없음)님의 프로필 이미지

2024. 09. 16. 17:01

답변 주셔서 감사합니다! 근데 만약 .padding을 200으로 진짜 말도 안되게 넓게 준다면 현재 화면에 있는 내용물들이 찌그러지더라도 여백을 확보 할 거라고 생각했는데 그렇지 안더라구요?? 이건 왜 그런 걸까요...?

 

추가)

일단 이어서 끝말잇기를 만들어 보고 있는데

struct ContentView: View {
    let title: String = "끝말잇기 게임"
    var body: some View {
        VStack {
            Text(title)
                .font(.title)
                .bold()
                .padding(.vertical) // 상하 패딩
                .padding(.horizontal, 20) // 좌우 패딩
                .background(
                    RoundedRectangle(cornerRadius: 15)
                        .fill(Color.teal)
                        .opacity(0.2)
                )
                .padding(.top, 10)
            //Spacer()
        }
    }
}

만약 위와 같이 코드를 작성하게 된다면 Text가 가운데에서 여백을 확보하기 위해 .top, 10만큼만 움직이는 걸 확인했습니다

 

분명 선생님께서 ".padding부분은 위아래에 다른 뷰가 없어서 패딩을 주나 안주나 똑같이 보이는것입니다. 위아래에 다른 뷰가 있다면 간격이 늘어날거에요"라고 말씀을 주셨는데 지금 현재 제가 올린 코드에서는 위에 뷰가 없는 상황임에도 분명 설정한 값만큼 padding이 되는 게 눈에 보이는데 왜 강아지 소개 코드에서는 .padding을 사용했는데 위 아래에 뷰가 없다고 해서 padding이 눈에 보이지 않는 건지 이유를 모르겠습니다..!

이 부분에 대해 답변 주시면 감사하겠습니다!!

좋은 강의 감사합니다 너무나 잘 듣고 있습니다
즐거운 추석 보내세요!

애구마(agmma)님의 프로필 이미지
애구마(agmma)
지식공유자

2024. 09. 27. 18:25

안녕하세요!

답변이 늦어서 죄송합니다!

 

답변 주셔서 감사합니다! 근데 만약 .padding을 200으로 진짜 말도 안되게 넓게 준다면 현재 화면에 있는 내용물들이 찌그러지더라도 여백을 확보 할 거라고 생각했는데 그렇지 안더라구요?? 이건 왜 그런 걸까요...?

이부분은 제가 확실히는 모르겠습니다.

SwiftUI의 레이아웃 법칙이 있는데 그부분을 읽어보시면 도움이 되지 않을까 싶어요

https://www.hackingwithswift.com/books/ios-swiftui/how-layout-works-in-swiftui

제가 도움받았던 영상인데요. 여기 보면

레이아웃의 원칙이

  1. A parent view proposes a size for its child.

  2. Based on that information, the child then chooses its own size and the parent must respect that choice.

  3. The parent then positions the child in its coordinate space.

  1. 부모 뷰가 자식 뷰에게 크기를 제안합니다.

  2. 그 정보를 바탕으로 자식 뷰는 자신의 크기를 선택하며, 부모는 그 선택을 존중해야 합니다.

  3. 그 후 부모는 자식을 자신의 좌표 공간 안에서 위치시킵니다.

이렇게 되는데요. 자식뷰가 자신의 크기를 선택할 때, 나름의 원칙이 있는거 같은데, 내부적으로 어떻게 작동하는지는 몰라서 그때그때 해봐야 아는거 같아요

 

 

그리고

 

.padding부분은

VStack내부에 있냐 없냐에 따라 다른거 같아요

첫번째 답변에서는 VStack바깥에 다른 뷰(형제뷰나 상위뷰)가 없어서 padding을 줘도 변함이 없었던거 같고

이번 예시에서는 상위뷰(VStack)이 있으니까 이 뷰의 자식같의 top padding을 10 준게 아닌가 싶습니다.

즉 다른뷰와의 관계가 없을때는 padding이 의미가 없고, 상위뷰나 형제뷰가 있어야 padding이 적용되는거 같아요

감사합니다!