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가 적용 안된것처럼 보이는 것
- frame(minHeight:)가 105로 설정하고 background()를 설정하면 105에 대한 background가 적용되지만,
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()
}