overlay
/ Background
/ Alignment
에 대해 알아보겠습니다.
ZStack
overlay
와 Background
를 이용하면 ZStack
에서 사용했던것 처럼 중첩된 뷰를 표현하는것이 가능합니다. 앞으로 자주 사용될 수식어이므로 함께 비교해서 알아봅시다. ZStack
은 특성상 그 나중에 작성한 green
사각형이 먼저 작성한 red
사각형보다 뷰 계층에서 상위에 위치합니다.
ZStack {
Rectangle()
.fill(Color.red)
.frame(width: 150.0, height: 150.0)
Rectangle()
.fill(Color.green)
.frame(width: 150.0, height: 150.0)
.offset(x: 10.0, y: 10.0)
}
이제 overlay
와 Background
를 사용해 이것과 동일한 결과를 만들어 내는 코드를 구현해 보겠습니다.
Overlay
overlay
는 뷰 원본의 공간을 기준으로 그 위에 새로운 뷰를 중첩하여 쌓는 기능을 하는 수식어 입니다.
UIKit
에서 addsSubview
메서드를 사용하는 개념과 같은데, 자식뷰를 추가하면 부모 뷰를 기준으로 프레임의 좌표가 결정되고 그 크기도 영향을 받았던 것을 생각해 보면 됩니다. ZStack
으로 구현한 코드를 overlay
를 이용해 구현하면 다음과 같이 작성 할 수 있습니다.
/*ZStack없이*/
Rectangle()
.fill(Color.red)
.frame(width: 150.0, height: 150.0)
.overlay( //오버레이 안에 직사각형을 또 추가한다.
Rectangle()
.fill(Color.green)
.offset(x: 10, y: 10))
Background
Background
수식어는 overlay
와 마찬가지로 뷰 원본의 공간을 기준으로 뷰를 중첩하는것은 같지만, 위가 아니라 그 아래 방향으로 쌓아 나간다는 점이 다릅니다.
지금까지 텍스트의 배경색을 지정해 줄 때 사용했던 이 수식어가 사실은 배경색을 지정하는 용도가 아니라, 뷰의 하위 계층에 지정한 색을 가진 또 다른 뷰를 추가하는 기능이었던 것입니다.
이번엔 Background
를 이용해 구현해 보면 다음과 같이 작성할 수 있습니다.
Rectangle()
.fill(Color.red)
.frame(width: 150.0, height: 150.0)
.background(Rectangle()
.fill(Color.green)
.offset(x: 20, y:20))
Alignment
두 수식어에는 공통으로 Alignment
매개 변수가 있어 추가되는 뷰의 위치를 설정해 줄 수도 있습니다.
이 매게 변수를 이용한 다른 예제를 살펴봅시다. padding(),alignment: . )
Circle()
.overlay(Image(systemName: "")
.font(.title)
.padding(),alignment: .top)
Circle()
.fill(Color.yellow.opacity(0.8)) //투명도설정
.frame(width: 250, height: 250)
//overlay
.overlay(Text("Joysitck")
.font(.largeTitle))
.overlay(Image(systemName: "arrow.up")
.font(.title)
.padding(),alignment: .top)
.overlay(Image(systemName: "arrow.left")
.font(.title)
.padding(),alignment: .leading) //왼쪽
.overlay(Image(systemName: "arrow.up.right.circle.fill")
.font(.title),alignment: .topTrailing) //오른쪽 위
//background
.background(Image(systemName: "arrow.right")
.font(.title)
.padding(),alignment: .trailing)
.background(Image(systemName: "arrow.down")
.font(.title)
.padding(),alignment: .bottom)
위의 방법을 ZStack를 사용하여 그대로 구현이 가능합니다.
내부적으로 뷰가 그려지는 방식은 다르더라도, 결과는 똑같은 모습으로 나타납니다.
ZStack {
//Circle전에 작성된 스택은 뒤로 가진다.
VStack {
Spacer() //아이콘이 아래 이니까 spacer를 먼저 작성
Image(systemName: "arrow.down")
.font(.title)
.padding()
}
HStack {
Spacer()
Image(systemName: "arrow.right")
.font(.title)
.padding()
}
Circle()
.fill(Color.yellow)
.opacity(0.8)
.frame(width: 250, height: 250 )
Text("Joystic")
.font(.largeTitle)
//Circle 위로 ZStack이 쌓아진다.
ZStack(alignment: .topTrailing) {
Color.clear
Image(systemName: "arrow.up.right.circle.fill")
.font(.title)
}
VStack {
Image(systemName: "arrow.up")
.font(.title)
.padding()
Spacer() //아이콘이 위 이니까 spacer를 나중에 작성
}
HStack {
Image(systemName: "arrow.left").font(.title).padding()
Spacer()
}
} //최상위 ZStack
.frame(width: 250, height: 250)
어느 것을 사용해야한다고 제약이 있는것은 아니지만, 일반적으로 다음과 같이 구분해서 생각해 볼 수 있습니다. 절대적인 기준이 아니므로 참고만 하는것이 좋습니다.
요약
.Overlay / Background
보통 수식 대상이 되는 뷰와 직접적인 연관성이 있는 뷰를 추가할 때 사용하며, 새로운 뷰가 더해진다는 점 외에는 다른 뷰에 영향을 주지 않는다. 그 자체로는 뷰가 아닌 단지 수식어로 존재하는 만큼, 전체 화면의 레이아웃을 구성할 때 사용되기보다 UI의 각 부분을 구성하는 개별적인 뷰 객체들을 꾸밀 때 활용한다.
ZStack
상대적으로 직접적인 연관성이 없는 뷰들을 계층 구조로 나열하여 UI를 구성해야 할 때 사용한다. 자식의 뷰의 크기에 따라 ZStack의 크기도 함께 변할 수 있으므로, overlay
/ Background
수식어를 사용했을 때와 달리 특정 콘텐츠의 변경 사항이 다른 뷰에까지 함께 영향을 줄 수 있 다는 것을 유의해야 한다.
읽어주셔서 감사합니다🤟
'SWIFTUI > View layout' 카테고리의 다른 글
SwiftUI : Stepper (onIncrement / onDecrement) (0) | 2021.01.25 |
---|---|
SwiftUI : ForEach (0) | 2021.01.24 |
SwiftUI : NavigationView / NavigationLink (4) | 2021.01.23 |
SwiftUI : HStack / Spacer / minLength / Frame (2) | 2021.01.22 |
SwiftUI : View layout (HStack / VStack / ZStack) (0) | 2021.01.22 |