일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- flutter #state # stateful #stateless
- IOS
- 코딩테스트
- 프로젝트회고
- 프로그래머스
- collectionView
- GIT
- 조건문
- Masil
- MVVM
- 청년취업사관학교후기
- UIKit
- flutter
- UserDefault
- 새싹후기
- Swift
- SwiftUI
- 백준
- WidgetTree
- 스터디
- xcode
- 스위프트
- ImageSlider
- CS193p
- colorofdays
- stanford
- 알고리즘
- xml
- process
- 오늘의 색상
- Today
- Total
개발을 시작하는 이야기
[SwiftUI] Lecture 2: Learning more about SwiftUI 본문
강의 보기 : YouTube :: Stanford
struct ContentView: View {
var body: some View {
HStack {
ZStack {
RoundedRectangle(cornerRadius: 20.0)
.stroke(lineWidth: 3)
Text("Hello, CS193p!")
}
ZStack {
RoundedRectangle(cornerRadius: 20.0)
.stroke(lineWidth: 3)
Text("Hello, CS193p!")
}
ZStack {
RoundedRectangle(cornerRadius: 20.0)
.stroke(lineWidth: 3)
Text("Hello, CS193p!")
}
ZStack {
RoundedRectangle(cornerRadius: 20.0)
.stroke(lineWidth: 3)
Text("Hello, CS193p!")
}
}
.padding(.horizontal)
.foregroundColor(.red)
}
}
HStack은 Horizontal Stack으로 수평으로 객체를 묶어주는 역할을 한다. 그럼 수직으로 묶는 건 VStack이 되겠다.
위 코드에서 ZStack이 반복되는 것을 볼 수 있다. 우리의 코드는 반복되는 것을 참을 수 없기 때문에 ZStack을 모듈화 하여 코드를 간결하게 유지하도록 한다.
struct ContentView: View {
var body: some View {
HStack {
CardView()
CardView()
CardView()
CardView()
}
.padding(.horizontal)
.foregroundColor(.red)
}
}
struct CardView: View {
var body: some View {
ZStack {
let shape = RoundedRectangle(cornerRadius: 20.0)
.stroke(lineWidth: 3)
Text("Hello, CS193p!")
}
}
}
이제는 CardView에서 클릭이벤트를 만들어준다.
struct CardView: View {
var content: String
@State private var isFaceUp: Bool = true
var body: some View {
ZStack {
let shape = RoundedRectangle(cornerRadius: 20.0)
if isFaceUp {
shape.fill().foregroundColor(.white)
shape.strokeBorder(lineWidth: 3)
Text(content).font(.largeTitle)
} else {
shape.fill()
}
}
.onTapGesture {
isFaceUp = !isFaceUp
}
}
}
Text가 들어갈 곳에는 content 변수를 사용해서 처리를 해주고,
카드의 앞면, 뒷면은 Bool Type을 사용하여 상태를 확인해주는데 여기서 @State 라는것이 등장한다.
@State - 상태프로퍼티
상태 프로퍼티는 뷰의 상태에 대한 가장 기본적인 형태이다. 상태 프로퍼티의 값이 변경되면 SwiftUI는 뷰를 다시 재 랜더링 하여 보여준다. 그렇다면 왜 상태 프로퍼티를 사용하는 것일까.
어느 두 개의 뷰가 있고 서로 바인딩되어 있다고 해보자. 어느 하나의 뷰에서 특정 프로퍼티의 값이 바뀔 때마다 다른 한 뷰도 실시간으로 업데이트되어야 할 때가 있는데 이때 사용하는 것이다.
상태 프로퍼티의 선언은 @State 프로퍼티 래퍼를 사용하며, 상태 프로퍼티의 값이 바뀔 때마다 바인딩된 모든 뷰들 역시 재 랜더링 된다. 한편, 상태 값은 해당 뷰에 대한 것이기 때문에 private 프로퍼티로 선언되어야 한다.
struct ContentView: View {
var emojis = ["💡", "📋", "🖥", "😺", "🗺", "😱", "🙈", "🤔", "📪", "👨🏫", "📱", "🎉", "📄", "💁", "📞", "👨💻", "⚒", "🙋", "🤵♂️", "😀", "😃", "😄", "😁"]
@State private var emojiCount = 20
var body: some View {
VStack {
ScrollView {
LazyVGrid(columns: [GridItem(.adaptive(minimum: 65))]) {
ForEach(emojis[0..<emojiCount], id: \.self, content: { emoji in
CardView(content: emoji).aspectRatio(2/3, contentMode: .fit)
})
}
}
Spacer()
HStack {
remove
Spacer()
add
}
.font(.largeTitle)
.padding(.horizontal)
}
.padding(.horizontal)
.foregroundColor(/*@START_MENU_TOKEN@*/.red/*@END_MENU_TOKEN@*/)
}
var remove: some View {
Button {
if emojiCount > 1 {
emojiCount -= 1
}
} label: {
Image(systemName: "minus.circle")
}
}
var add: some View {
Button {
if emojiCount < emojis.count {
emojiCount += 1
}
} label: {
Image(systemName: "plus.circle")
}
}
}
ForEach 구문은 이모지를 각각의 뷰에 순서대로 넣어주게 된다. Swift의 forEach() 방식과 비슷하지만 눈에 띄는 차이점은 id: \. self라고 할 수 있다. 배열의 각 요소를 고유하게 식별할 수 있도록 해주는 요소이다. Array 내부 요소가 가지고 있는 값 자체를 id 값으로 설정을 해준다. 위 경우에는 💡는 id 값으로 💡를, 📋는 id 값으로 📋를 갖는다고 볼 수 있다. 그래서 만일 Array에서 값이 중복이 된다면 id값이 동일하게 설정되어 같은 값으로 인식될 수 있으니 주의해야 한다.
LazyVGrid를 살펴보자
Lazy는 LazyVStack , LazyHStack , LazyVGrid , LazyHGrid와 같이 Lazy가 붙은 뷰 빌더들을 볼 수 있는데, Swift에서 Lazy와 함께 선언된 프로퍼티는 처음 호출될 때 값을 계산하게 된다. 그래서 필요하지 않은 시간 동안은 값을 생성하지 않기 때문에 데이터를 효율적으로 사용할 수 있다.
V는 Vertical
Grid는 List와 함께 비교하여 많이 설명되는데, List는 Vertical Direction으로, TableView와 흡사하다. Grid는 Horizontal Direction으로, CollectionView와 흡사하다. Instagram / Pinterest / Netflix의 레이아웃을 떠올리면 된다.
그럼 LazyVGrid는 호출되기 전엔 값을 생성하지 않는 세로 형태의 아이템 레이아웃이라고 할 수 있다.
Spacer()는 객체와 객체 사이의 공간을 만들어주는 역할을 하는데 객체의 크기를 해치지 않는 선에서 최대의 공간을 갖게 된다.
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.preferredColorScheme(.light)
.previewInterfaceOrientation(.portrait)
ContentView()
.preferredColorScheme(.dark)
}
}
Priview의 ContentView를 두 개를 만들어 light모드와 Dark 모드를 모두 볼 수 있게 해 준다
참조 : LazyVGrid, ForEach, Spacer
'개발 이야기 > Swift' 카테고리의 다른 글
[SwiftUI] Lecture 4: Memorize Game Logic (0) | 2022.04.14 |
---|---|
[SwiftUI] Lecture 3: MVVM and the Swift type system (0) | 2022.04.12 |
[SwiftUI] Lecture 1: Getting started with SwiftUI (0) | 2022.04.08 |
UIKit (0) | 2022.04.05 |
Foundation (0) | 2022.04.04 |