SwiftUI 이벤트 수정자와 생명주기
앱을 만들 때 특정 뷰를 레이아웃 안에 나타나거나 사라지게 하는 일련의 작업을 수행해야하는 경우가 있다 이런 경우 앱은 값이 변경될 때마다 일부 코드를 실행하거나 뷰를 활성화 비활성화 시켜야하는 시점을 감지해야 한다 이런 모든 요구사항 또는 그 이상은 swiftUI에서 제공하는 이벤트 수정자 세트를 사용하면 충족이 가능하다
onAppear & onDisappear 수정자
가장 기본적이고 자주 사용되는 수정자이고 각각 수정자가 사용된 뷰가 사라지거나 나타난 경우에 작업을 수행한다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// contentview.swift
import SwiftUI
struct ContentView: View {
var body: some View {
TabView {
SwiftUIView()
.tabItem {
Image(systemName: "1.circle")
Text("SwiftUI")
}
SwiftUIView2()
.tabItem {
Image(systemName: "2.circle")
Text("SwiftUI2")
}
}
}
}
#Preview {
ContentView()
}
위 파일에 탭 뷰를 사용해서 서로 다른 뷰를 표시하게 했다 그리고 각각의 뷰를 생성한다 (SwiftUIView, SwiftUIView2를 생성)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// SwiftUIView.swift
import SwiftUI
struct SwiftUIView: View {
var body: some View {
Text("view1")
.onAppear(perform: {
print(" on appear triggered")
})
.onDisappear(perform: {
print(" on disappear triggered")
})
}
}
#Preview {
SwiftUIView()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
// SwiftUIView2.swift
import SwiftUI
struct SwiftUIView2: View {
var body: some View {
Text("view2")
}
}
#Preview {
SwiftUIView2()
}
사진에서 보이는것 처럼 view1이 보인다면 on appear가 출력되고 탭2를 눌러서 view2를 출력한다면 해당 뷰가 사라졌기 때문에 on disappear가 출력된다
onChange 수정자
onChange수정자는 앱내에서 상태가 변경될 때마다 작업을 수행해야 할 때 사용한다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//swiftUIView2.swift
import SwiftUI
struct SwiftUIView2: View {
@State private var text: String = ""
var body: some View {
TextEditor(text: $text)
.padding()
.border(Color.red, width: 1)
.frame(height: 50) // 원하는 높이 설정
.onChange(of: text) { newValue in
print("onchange triggered: \(newValue)")
}
}
}
#Preview {
SwiftUIView2()
}
텍스트 에디터에 값을 넣을때 마다 실행된다
ScenePhase와 onChange
ScenePhase는 현재 화면의 상태를 저장하기 위해 사용하는 @Enviroment속성이다 ScenePhase에 대한 변경사항이 onChange수정자에 의해 모니터링 된다면 앱이 포그라운드 -> 백그라운드 or 백그라운드 -> 포그라운드 전환시 실행될 작업을 지정할 수 있다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// lifecycleApp.swift
import SwiftUI
@main
struct lifecycleApp: App {
@Environment(\.scenePhase) private var scenePhase
var body: some Scene {
WindowGroup {
ContentView()
}
.onChange(of: scenePhase) { phase in
print("Scene Phase: \(phase)")
}
}
}
active 상태: 화면이 포그라운드에 있으며 사용자에게 표시, 인터랙션에 반응
inactive 상태: 비활성화 상태로 포그라운드에 있고 사용자에게 표시되지만 인터랙션에 반응하지 않음( 멀티태스킹 화면으로 전환될 때 잠시 비활성 상태가 됨 )
background 상태: 사용자에게 화면이 표시되지 않는다
비동기 작업 뷰에 반영하기
비동기 작업을 사용해서 text뷰에 다른 문자열을 표시한다 처음 뷰가 생성될때는 view1을 출력하지만 비동기 작업이 이루어지고 나서 타이틀을 변경한다
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
//SwiftUIView.swift
import SwiftUI
struct SwiftUIView: View {
@State var title = "view 1"
var body: some View {
Text(title)
.onAppear(perform: {
print(" on appear triggered")
})
.onDisappear(perform: {
print(" on disappear triggered")
})
.task (priority: .background){ //우선순위 늦추기
title = await changeTitle()
}
}
func changeTitle() async -> String {
sleep(5) //5초를 지연시켜 반영을 확인한다
return "view another"
}
}
#Preview {
SwiftUIView()
}