티스토리 뷰
어떤때에 뭘 써야할지 헷갈렸는데 내가 이해한대로 대충 정리해보면 이런 느낌인 것 같다.
- State는 뷰 내에서 소박하게,,
- Observable은 외부클래스를 여러 다른 뷰에서 사용가능하지만 다른 뷰로 이동시 계속 넘겨줘야한다. (앱 내의 여러 뷰가 동일한 구독객체에 접근해야하는 경우 복잡해질 수 있다고 한다.)
- Environment는 별도로 값을 전달하지 않아도 모든 뷰에서 사용 가능하다.
@ : 프로퍼티 래퍼
$ : Binding ( $ 어묵꼬치처럼 생겼는데 꼬챙이로 찍어서 연결시킨다고 생각하면,, 될까,,)
@State 상태프로퍼티 | ObservableObject | EnvironmentObject |
- 해당 View내에서만 사용 - private 형태 - 여러 뷰에서 동시에 State값을 참고하고 싶다면 @Binding을 사용 - Toggle, TextField 에서 사용 @State private var 변수명 $변수명 |
- 여러 다른 View 안에서 외부 클래스를 사용할 수 있게된다. - 타이머나 알림 - 네비게이션 링크로 뷰에서 다른 뷰로 이동할때 동일한 구독 객체에 접근해야한다. ObservableObject @Published @ObservedObject |
별도로 값을 전달해주지 않아도 모든 뷰에서 사용가능 @Environment |
@State
import SwiftUI
struct ContentView: View {
@State private var toggleOn: Bool = true
@State private var userName: String = ""
var body: some View {
VStack {
Toggle(isOn: $toggleOn) {
Text(toggleOn ? "\(Image(systemName: "wifi")) Wi-Fi On" : "\(Image(systemName: "wifi.slash")) Wi-Fi Off")
}
TextField("이름을 입력하세요.", text: $userName)
.padding()
Text(userName)
.frame(width: 380,height: 50)
.border(.black, width: 3)
}
.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
여러 뷰에서 동시에 State값을 참고하고 싶다면 @Binding을 사용
import SwiftUI
struct ContentView: View {
@State private var toggleOn: Bool = true
@State private var userName: String = ""
var body: some View {
VStack {
Toggle(isOn: $toggleOn) {
Text(toggleOn ? "\(Image(systemName: "wifi")) Wi-Fi On" : "\(Image(systemName: "wifi.slash")) Wi-Fi Off")
}
SubView(userInfo: $userName)
}
.padding()
}
}
struct SubView: View {
@Binding var userInfo: String
var body: some View{
VStack{
TextField("이름을 입력하세요.", text: $userInfo)
.padding()
Text(userInfo)
.frame(width: 380,height: 50)
.border(.black, width: 3)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
ObservableObject
(앱파일(?)과 프리뷰에도 수정 필요함)
Observable 과 Observed 헷갈림 주의...
게시자와 구독자의 관계로 생각하면 쉽다고 한다.
Observable 객체를 구독하기 위해 @ObservedObject 프로퍼티 래퍼를 사용.
(유튜버와 구독자들이라고 생각해보면 ,,,
유튜버가 영상을 게시하면 모든 구독자들에게 전달된다. 내용이 바뀌면 바뀐 내용으로 전달됨)
그냥 내 생각이라 틀릴 수도 있으니 무시해주세요
import SwiftUI
@main
struct VlogDemoSOEApp: App {
var body: some Scene {
WindowGroup {
ContentView(countUp: CountUp())
//앱파일(?)에 이부분도 수정해야함
}
}
}
import SwiftUI
struct ContentView: View {
@ObservedObject var countUp: CountUp
var body: some View {
VStack {
Text("Count : \(countUp.count)")
.padding()
Button("누르면 +1 되는 버튼") {
countUp.up()
}
}
.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(countUp: CountUp())
//프리뷰도 수정 필요
}
}
// CountUp이라는 이름을 가진 swift파일을 새로 만들어서
// ObservableObject을 상속받은 class를 만들어줌
import Foundation
class CountUp: ObservableObject {
@Published var count: Int = 0
func up(){
count += 1
}
}
앱 내의 여러 뷰가 동일한 구독객체에 접근해야하는 경우
import SwiftUI
struct ContentView: View {
@ObservedObject var countUp: CountUp
var body: some View {
NavigationView{
VStack {
Text("Count : \(countUp.count)")
.padding()
Button("누르면 +1 되는 버튼") {
countUp.up()
}
.padding()
NavigationLink(destination: NextView(countUp: countUp)){
//NavigationLink로 뷰에서 다른 뷰로 이동할때 동일한 구독 객체에 접근해야한다.
//NavigationLink로 NextView로 이동할 때 전달해야한다.
Text("NEXT")
}
}
.padding()
}
}
}
import SwiftUI
struct NextView: View {
@ObservedObject var countUp: CountUp
var body: some View {
Text("\(countUp.count)")
}
}
struct NextView_Previews: PreviewProvider {
static var previews: some View {
NextView(countUp: CountUp())
}
}
EnvironmentObject
(앱파일(?)과 프리뷰에도 수정 필요함)
import SwiftUI
@main
struct VlogDemoSOEApp: App {
var body: some Scene {
WindowGroup {
ContentView().environmentObject(CountUp())
//앱파일(?)에 이부분도 수정해야함
}
}
}
import SwiftUI
struct ContentView: View {
@EnvironmentObject var countUp: CountUp
var body: some View {
NavigationView{
VStack {
Text("Count : \(countUp.count)")
.padding()
Button("누르면 +1 되는 버튼") {
countUp.up()
}
.padding()
NavigationLink(destination: NextView()){
// 안 넘겨도 됨!
Text("NEXT")
}
}
.padding()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environmentObject(CountUp())
//프리뷰도 수정 필요
}
}
import SwiftUI
struct NextView: View {
@EnvironmentObject var countUp: CountUp
var body: some View {
Text("\(countUp.count)")
}
}
struct NextView_Previews: PreviewProvider {
static var previews: some View {
NextView().environmentObject(CountUp())
}
}
// CountUp이라는 이름을 가진 swift파일은 동일
import Foundation
class CountUp: ObservableObject {
@Published var count: Int = 0
func up(){
count += 1
}
}
'SwiftUI' 카테고리의 다른 글
Error Domain=NSURLErrorDomain Code=-1200 해결하기 (0) | 2022.12.01 |
---|
댓글