momodudu.zip
#2 SwiftUI - View Layout 본문
이번에는 UIView에 사용되는 몇가지 레이아웃을 살펴보고자 한다~
1. 스택
UIKit의 스택은 UIStackView와 대충 매치된다고 생각하면 될 것 같다. 스택 안에 여러가지 뷰들을 배치할 수 있고, 버티컬과 호라이즌, 뎁스 스택이 존재한다. 간단한 예제를 한번 보자.
ContentView에 기본 컨테이너를 VStack, 버티컬 스택으로 지정한 후 각 스택 컨테이너마다 Text 컨텐츠를 추가해준 모습이다.
struct ContentView: View {
var body: some View {
VStack {
Text("Hello, World!")
.foregroundColor(.red)
Text("Hello, Swift!")
.foregroundColor(.blue)
}
}
}
위 코드에서 사실 버티컬 스택이 없이 Text("Hello, World!")와 Text("Hello, Swift!")를 두가지를 넣는다면 컴파일 에러가 발생한다. 하나의 Text만 리턴해야되니까... 그런데 이 두가지 컨텐츠를 버티컬 스택 컨테이너로 감싸면서, 실제로 마지막에 리턴되는 뷰는 스택이 될 것이다. 실제로 이 스택의 선언부로 들어가보면, 생성자를 지정할수도 있다.
/// Creates an instance with the given `spacing` and Y axis `alignment`.
///
/// - Parameters:
/// - alignment: the guide that will have the same horizontal screen
/// coordinate for all children.
/// - spacing: the distance between adjacent children, or nil if the
/// stack should choose a default distance for each pair of children.
@inlinable public init(alignment: HorizontalAlignment = .center, spacing: CGFloat? = nil, @ViewBuilder content: () -> Content)
얼라인먼트와 스페이싱을 지정할 수 있는듯 하다. 스페이싱은 설명을 보니 storyboard로 UI를 구성했을 때 constraints를 지정해주는것과 비슷한 역할을 하는것 같다.
struct ContentView: View {
var body: some View {
VStack {
Text("Hello, World!")
.foregroundColor(.red)
Text("Hello, Swift!")
.foregroundColor(.blue)
}
.padding()
.border(Color.red)
}
}
스택 역시 뷰의 한 종류이므로, 위와 같이 패딩이나 보더도 지정해줄 수 있다. 오.. 이제 느낌이 좀 오는군
이렇게 컨테이너 자체에 효과를 주는것도 있고, 컨테이너에 딸리는 자식들(컨텐츠)에 효과를 주는 수식어들도 있다.
var body: some View {
VStack {
Text("Hello, World!")
.foregroundColor(.red)
Text("Hello, Swift!")
.foregroundColor(.blue)
}
.font(.headline)
.padding()
.border(Color.red)
}
위 코드에서 스택에 딸리는 수식어 폰트는 실제로 그 자식들에게 영향을 미친다. 물론! 컨테이너 내의 컨텐츠마다 .font로 지정해줄수도 있지만 위처럼 컨테이너 자식들에게 일괄적용도 시킬 수 있다. 오~ 박수박수
2. Spacer
스페이서는 스택내부에서 사용될때와 외부에서 사용할 때 약간 다르게 동작한다고 한다. 스택 외부에서 사용될때는 부모뷰에 종속되고, 부모뷰가 제공하는 공간에 한해서는 최대 확장을 한다.
struct ContentView: View {
var body: some View {
Spacer()
.background(Color.blue)
}
}
이렇게 위와같은 경우에는 부모 최상단 뷰에 종속적이므로 화면 전부의 배경컬러가 파란색으로 보인다~
하지만 이 컨테이너를 스택으로 감싼다면! 스페이서 내부에는 아무런 컨텐츠가 없으므로 스택에서는 없는것처럼 동작하기 때문에, 아무런 색깔도 나타나지 않는다. 스페이서가 차지하는 영역을 확인하기 위해서 스택에 간단한 컨텐츠를 넣어보자.
struct ContentView: View {
var body: some View {
VStack{
Spacer()
Text("TextArea")
.background(Color.red)
}
.background(Color.blue)
}
}
오~ 코드와 프리뷰를 보니 스페이서가 스택 내부에서 어떻게 동작하는지 알 수 있다. 스페이서는 부모뷰에 종속되며, 가질 수 있는 최대 크기를 갖는다!
3. Overlay, Background
오버레이와 백그라운드는 중첩된뷰를 만들 때 주로 사용한다고 한다. 이게 UIKit에도 있던건가...? 싶었는데 보다보니 UIKit에서 addSubviews를 하던것과 똑같은 원리라고 한다! 아하~ 오키오키
오버레이와 백그라운드는 둘다 뷰를 중첩하는 수식어들인데, 차이점이라고 한다면 오버레이는 parent view를 기준으로 뷰가 중첩되며, child view의 크기 또한 parent view의 영향을 받는다. 즉 child가 parent위로 차곡차곡 쌓인다.
반면 백그라운드는 현재 뷰를 기준으로 중첩 방향이 위가 아니라 아래로 향한다. 놀라운점은 이제까지 사용했던 background 수식어가 이 백그라운드와 같은 개념이라는것 !!!!
struct ContentView: View {
var body: some View {
Circle()
.fill(Color.yellow)
}
}
간단하게 위와 같이 노란 원을 추가했다. 여기서 오버레이와 백그라운드의 차이점을 명확하게 보고자 한다~
struct ContentView: View {
var body: some View {
Circle()
.fill(Color.yellow)
.background(Color.black.opacity(0.5))
}
}
위와 같이 노란원이 그려진 뷰를 기준으로 백그라운드에 알파가 0.5인 검은색 뷰를 하나 추가한다.
예상한대로(?) 결과는 위와 같이 검은색 배경이 깔렸다. 그렇다면 오버레이는?
struct ContentView: View {
var body: some View {
Circle()
.fill(Color.yellow)
.overlay(Color.black.opacity(0.5))
}
}
짠~ 노란 원이 그려진 뷰를 기준으로 "위로" 검은색 뷰가 쌓인다. 오~
처음 SwiftUI 코드를 봤을땐 뭔가 단순한데 엄청 알아듣기 어렵다...;; 같은 느낌이었는데 조금 써보니까 확실히 UI면에선 진입장벽이 훨씬 낮은느낌이다!! 오히려 약간 마크다운 랭귀지같은 느낌~!
'ios > SwiftUI' 카테고리의 다른 글
#4 SwiftUI의 Coordinator (2) | 2020.08.25 |
---|---|
#3 SwiftUI에서 Swift UIKit 사용하는것에 대해 - UIRepresentable (0) | 2020.08.14 |
#1 SwiftUI - SwiftUI 시작해보기 Hello, World! (0) | 2020.06.07 |