Notice
Recent Posts
Recent Comments
Link
관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - SwiftUI] 뷰 속성 순서의 중요성 (SwiftUI 뷰 구현 중 놓치는 것) 본문

iOS 응용 (swift)

[iOS - SwiftUI] 뷰 속성 순서의 중요성 (SwiftUI 뷰 구현 중 놓치는 것)

jake-kim 2024. 12. 12. 01:22

뷰 속성 순서의 중요성

  • SwiftUI에서는 뷰를 선언하고 속성을 선언적으로 넣어주어서 뷰를 완성해나가는데, 속성을 넣을때 순서도 중요

ex) 아래 firstView, secondView는 frame(minHeight:)의 선언 순서만 다르고 나머지는 동일한 코드지만 완전히 다른 뷰가 보여짐

@ViewBuilder
private var firstView: some View {
    VStack(spacing: 0) {
        Color.clear
            .frame(width: 287, height: 0)
        
        Text("테스트 문구")
    }
    .frame(minHeight: 105) // <-
    .background(Color.green)
    .clipShape(RoundedRectangle(cornerRadius: 20))
    .padding(.top, 24)
}

@ViewBuilder
private var secondView: some View {
    VStack(spacing: 0) {
        Color.clear
            .frame(width: 287, height: 0)
        
        Text("테스트 문구")
    }
    .background(Color.green)
    .clipShape(RoundedRectangle(cornerRadius: 20))
    .padding(.top, 24)
    .frame(minHeight: 105) // <-
}
  • frame(minHeight:) 순서 위치만 다른데, 아래처럼 두 뷰를 VStack안에 넣어서 확인해보면 secondView의 height가 적은 것을 확인 가능
struct ContentView: View {
    var body: some View {
        VStack(spacing: 12) {
            firstView
            secondView
        }
    }
}

SwiftUI에서 순서의 중요성

  • frame, backgroundColor와 같은 속성들을 선언하고 결과를 보면 이것들을 종합하여 한번에 적용할 것 같지만, SwiftUI에서는 순서에 독립적이지 않음
    • frame(minHeight:)가 105로 설정하고 background()를 설정하면 105에 대한 background가 적용되지만, 
      backgroun()를 먼저 설정하고 frame(minHight:)를 주게되면 Text("test")영역만 background로 입혀진 후 나머지는 frame(minHight:)가 적용되어 투명 영역의 프레임이 늘어나서 마치 105가 적용 안된것처럼 보이는 것
Text("test")    
    .frame(minHeight: 105) // <- 크기를 먼저 늘리고 색상을 적용하여, 색상이 105만큼 적용됨
    .background(Color.green)

Text("test")    
    .background(Color.green)
    .frame(minHeight: 105) // <- 색상보다 크기가 나중에 적용되어, 크기가 늘어난 부분은 투명으로 보일 것

결론

  • SwiftUI에서 뷰를 구현에 각각 속성을 위에서 아래로 적용할 때, 순서가 뷰에 영향을 미친다는 것을 기억하고 항상 속성을 적용할 땐 바로 위에 있는 속성에 이 속성을 부여한다는 의미를 알고 구현할 것

* 전체 코드

import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack(spacing: 12) {
            firstView
            secondView
        }
    }
    
    @ViewBuilder
    private var firstView: some View {
        VStack(spacing: 0) {
            Color.clear
                .frame(width: 287, height: 0)
            
            Text("테스트 문구")
        }
        .frame(minHeight: 105) // <-
        .background(Color.green)
        .clipShape(RoundedRectangle(cornerRadius: 20))
        .padding(.top, 24)
    }
    
    @ViewBuilder
    private var secondView: some View {
        VStack(spacing: 0) {
            Color.clear
                .frame(width: 287, height: 0)
            
            Text("테스트 문구")
        }
        .background(Color.green)
        .clipShape(RoundedRectangle(cornerRadius: 20))
        .padding(.top, 24)
        .frame(minHeight: 105) // <-
    }
}

#Preview {
    ContentView()
}
Comments