일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 | 30 |
- Android 13
- Observable
- mvvm
- MotionLayout
- Animation
- databinding
- GCP
- android13
- 동영상
- node
- MediaPlayer
- 인앱결제
- junit
- Koin
- 테스트 자동화
- liveData
- mysql
- SwiftUI Tutorial
- paging
- RxKotlin
- list
- Android
- MediaSession
- Kotlin
- SWIFTUI
- Reactive
- PagingLib
- node.js
- rx
- google play
- Today
- Total
봄날은 갔다. 이제 그 정신으로 공부하자
1. SwiftUI Tutorial - @main, @State, @Binding 본문
이 글은 swiftUI Tutorial 중 1번째 항목인 "Creating and Combining Views" 내용을 기반으로 소소하게 알아두면 좋은 내용을 설명합니다.
swiftUI Tutorial "Creating and Combining Views"(아래 링크)와 같이 보시면 더욱 유익합니다.
https://developer.apple.com/tutorials/swiftui/creating-and-combining-views
@main
swiftUI로 앱을 구현할 때 해당 앱의 진입접을 제공하는 어노테이션으로 App을 상속받은 구조체 위에 반드시 @main 어노테이션을 명시해야 하면 한개의 앱에 한개의 @main 어노테이션만 존재해야 합니다.
프로젝트 생성 시 SwiftUI를 기본으로 선택하면 자동으로 추가됩니다.
사용 방법은 아래와 같습니다.
import SwiftUI
@main
struct MyLandmarkApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
@State
@State 어노테이션은 View가 접근 가능하도록 값을 가지고 있는 Property Wrapper로 Swift 5.1부터 추가된 어노테이션입니다.
Property Wrapper는 개발자가 별도의 코딩 없이 어노테이션만 선언해도 View에서 수정이나 읽기가 가능하도록 캡슐화를 대신해줍니다.
단, @State는 UI의 상태 값과 같은 아주 한정된 용도로만 사용하기를 권고하는데 그 이유는 View 안에만 사용하는 메모리 공간이기 때문으로 View 밖의 클래스에서 사용하기를 원한다면 ObservableObejct를 사용하는 것이 좋습니다.
@State의 사용 방법은 아래와 같습니다.
import SwiftUI
import MapKit
struct MapView: View {
@State private var region = MKCoordinateRegion(
center: CLLocationCoordinate2D(latitude: 34.011_286, longitude: -116.166_868),
span: MKCoordinateSpan(latitudeDelta: 0.2, longitudeDelta: 0.2)
)
var body: some View {
Map(coordinateRegion: $region)
}
}
struct MapView_Previews: PreviewProvider {
static var previews: some View {
MapView()
}
}
@Binding
위에서 @State에 대해 설명하면서 @State는 선언된 View 안에만 사용하는하므로 외부 클래스에서 사용하기를 원한다면 ObservableObejct를 사용하는 것이 좋다고 하였는데 @Binding 어노테이션을 사용하여 State값을 받는 것만으로 여러 개의 View가 동시에 State값을 참조하는 방식도 있습니다. 다만 State는 View 안에만 사용하는 메모리 공간이기 때문에 Toggle 유무와 같은 UI의 상태 값과 같은 아주 한정된 용도로만 사용하기를 권고하고 있습니다.
사용 방법은 아래와 같습니다.
* @Binding은 SwiftUI Tutorial 3: handling-user-input에서 언급되는 내용이지만 흐름상 @State와 함께 설명하는 것이 적절해 보여 같이 설명하였습니다.
// LandmarkDetail View에 "좋아요" 버튼(FavoriteButton)을 추가하고 isFavorite 값을 넘겨 줍니다.
struct LandmarkDetail: View {
@EnvironmentObject var modelData: ModelData
var landmark: Landmark
var landmarkIndex: Int {
modelData.landmarks.firstIndex(where: {$0.id == landmark.id})!
}
var body: some View {
ScrollView {
MapView(coordiante: landmark.locationCoordinate)
.ignoresSafeArea(edges: .top)
.frame(height: 300)
CircleView(image: landmark.image)
.offset(y: -130)
.padding(.bottom, -130)
VStack(alignment: .leading) {
HStack {
Text(landmark.name)
.font(.title)
FavoriteButton(isSet: $modelData.landmarks[landmarkIndex].isFavorite)
}
HStack {
Text(landmark.park)
Spacer()
Text(landmark.state)
}
.font(.subheadline)
Divider()
VStack(alignment: .leading) {
Text("About \(landmark.name)")
.font(.title2)
Text(landmark.description)
}
}
.padding()
}
.navigationTitle(landmark.name)
.navigationBarTitleDisplayMode(.inline)
}
}
// isFavorite 값을 토글할 FavoriteButton View를 아래와 같이 작성해줍니다.
struct FavoriteButton: View {
@Binding var isSet: Bool
var body: some View {
Button {
isSet.toggle()
} label: {
Label("Toggle Favorite",
systemImage: isSet ? "star.fill" : "star")
.labelStyle(.iconOnly)
.foregroundColor(isSet ? .yellow : .gray)
}
}
}
LandmarkDetail View에서 FavoriteButton(isSet: $modelData.landmarks[landmarkIndex].isFavorite) 코드를 통해
FavoriteButton에 isFavorite 값을 넘겨주었고 FavoriteButton View에서는 @Binding을 통해 넘겨받은 isFavorite을 토글을 통해 변경 시켜주었습니다.
'iOS Tip' 카테고리의 다른 글
3-1. SwiftUI Tutorial - List filter & sort (0) | 2022.03.08 |
---|---|
2-2. SwiftUI Tutorial - List (0) | 2022.03.04 |
2-1. SwiftUI Tutorial - Hashable, Codable, Identifiable (0) | 2022.03.01 |
swift optional 제거 방법 (0) | 2022.02.22 |
ViewController 호출 (0) | 2022.02.10 |