SwiftUI Lecture 8.
- UserDefaults
Lightweight persistent store - Gestures
Getting input from the user into your app
Storing Data Permanently
numerous ways to make data “persist” in iOS
simplest UserDefaults
In a SQL database (CoreData for OOP access or even direct SQL calls).
iCloud (interoperates with both of the above)
CloudKit (a database in the cloud)
UserDefaults
- Using UserDefaluts
UserDefaults instance 생성
let defaults = UserDefaults.standard
- Storing Data
딕셔너리 형식으로 저장.
defaults.set(object, forKey: “SomeKey”) // object must be a Property List
- Retrieving Data
let i: Int = defaults.integer(forKey: “MyInteger”)
let b: Data = defaults.data(forKey: “MyData”)
let u: URL = defaults.url(forKey: “MyURL”)
let strings: [String] = defaults.stringArray(forKey: “MyString”)
// etc.
String이 아닌 배열을 가져오기에는 좀 더 복잡할 수 있다.
let a = array(forKey: “MyArray”) //는 Array<Any>를 반환한다...
따라서 Swift의 'as' 연산자를 이용해 이 Array element들을 "type cast" 해주어야 하는데, (*typecasting?)
혹은 data(forKey:) 를 사용하여 이를 Codable로 쉽게 해결할 수도 있다.
Gestures
: Getting Input from the User
사용자의 손가락 '제스처' (= multitouch)를 감지하는 SwiftUI
우리는 이러한 제스처들이 감지되면 어떻게 다루어야 할까.
- How to make Views recognize Gestures
To cause your View to start recognizing a certain gesture, you use the .gesture View modifier.
myView.gesture(theGesture) // theGesture must implement the Gesture protocol
- Creating a Gesture
var theGesture: some Gesture {
return TapGesture(count: 2)
}
- Handling the Recognition of a Discrete Gesture
감지된 제스터를 어떻게 처리하는가는, 그 제스터가 discrete한가 아닌가에 따라 달라진다.
Discrete Gesture :
It happens “all at once” and just does one thing when it is recognized. (e.g. TapGesture)
(반면 pinch나 drag는 happening overtime)
discrete gesture를 감지하고 처리하기 위해서는 .onEnded { } 를 사용한다.
var theGesture: some Gesture {
return TapGesture(count: 2)
.onEnded { /* do something */ }
}
더욱 편리한 버전으로 사용하기 위해서는 다음과 같은 방식으로 많이 사용된다.
myView.onTapGesture(count: Int) { /* do something */ }
myView.onLongPressGesture(...) { /* do something */ }
- Handling Non-Discrete Gestures
조금 더 복잡한 non-discrete gestures 다루기
처음 제스처가 감지되었을 때 뿐만아니라, 제스처가 끝났을 때도 감지해줘야함.
need to handle the gesture while it is in the process of happening (fingers are moving)
(e.g. DragGesture, MagnificationGesture(pinch), RotationGesture 등)
LongPressGestrure도 non-discrete으로 취급될 때가 있다? (fingers down and fingers up)
var theGesture: some Gesture {
DragGesture(...)
.onEnded { value in /* do something */ }
}
여기서도 .onEnded { }를 사용해 제스처가 끝날 때 실행할 것들을 알려줘야 하는데,
discrete gestures와 다른 점은, 해당 제스처가 끝났을 때의 state를 알려주기 위해 클로저에 value 인자를 같이 넘겨준다는 것!
여기서 넘겨줘야할 value 인자는 해당 제스처 마다 다르다.
For a DragGesture, it’s a struct with things like the start and end location of the fingers.
For a MagnificationGesture it’s the scale of the magnification (how far the fingers spread out).
For a RotationGesture it’s the Angle of the rotation (like the fingers were turning a dial).
또한, non-discrete gesture 에서는 제스처가 일어나는 동안 변화하는 state를 감지하고 update해야하는 경우가 있을 수 있다.
이러한 변화 중의 state는 @GestureState을 이용해 다음과 같이 저장할 수 있다. 여기서 var는 어떤 type 이던 상관없다.
@GestureState var myGestureState: MyGestureStateType = <starting value>
@GestureState is only the state while the Gesture is active.
This var will always return to <starting value> when the gesture ends.
제스처가 이루어지고 있는 중에만 state의 변화를 저장할 수 있도록, 제스처가 끝난 후에는 시작 value로 돌아가도록 되어있다.
@GestureState var의 상태(손가락 움직임)는 .updating을 사용해 다음과 같이 계속해서 업데이트해줄 수 있다.
var theGesture: some Gesture {
DragGesture(...)
.updating($myGestureState) { value, myGestureState, transaction in
myGestureState = /* usually something related to value */
}
.onEnded { value in /* do something */ }
}
@GestureState 없이 .onChanged 를 사용해서 좀더 심플하게 다음과 같이 구현해줄 수도 있다.
var theGesture: some Gesture {
DragGesture(...)
.onChanged { value in
/* do something with value (which is the state of the fingers) */
}
.onEnded { value in /* do something */ }
}
그림그리기 같은 실제 손가락의 위치를 받아오는 경우 이렇게 .onChanged 를 사용해 더 간단하게 구현해줄 수 있지만,
보통의 경우 실제 값이 아닌 상대적인 위치를 비교하여 제스처를 인식하는 경우가 많은데, 그럴 때에는 .updating()을 이용해서 구현해주어야 한다.
참고 : Stanford iOS SwiftUI
'Swift iOS 앱 개발 > Swift 튜토리얼' 카테고리의 다른 글
[Stanford iOS] Lecture 12. Core Data (0) | 2021.04.13 |
---|---|
[Stanford iOS] Lecture 9. Data Flow (0) | 2021.04.12 |
[Stanford iOS] Lecture 7. Multithreading EmojiArt (0) | 2021.04.09 |
[Stanford iOS] Lecture 6. Animation (0) | 2021.04.09 |
[Stanford iOS] Lecture 5. ViewBuilder + Shape + ViewModifier (0) | 2021.04.08 |