SwiftUI : onAppear()
onAppear()
View
가 나타날 때 실행될acttion을
추가합니다.
SwiftUI
는 UIKit
의 ViewDidDisplay()
와 동등한 기능을 제공합니다. 원하는 모든 코드를 이 두 이벤트에 첨부할 수 있고, SwiftUI
는 이벤트가 발생할 때 이것을 실행합니다.
즉 특정 뷰가 화면에 나타날 때 특정 항목을 로드합니다.
struct ContentView: View {
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: DetailView()) {
Text("onAppear() & onDisappear()")
}
}
}
}
}
struct DetailView: View {
var body: some View {
VStack {
Text("Second View")
}
.onAppear {
print("DetailView가 실행되었습니다.")
}
.onDisappear {
print("DetailView가 종료되었습니다.")
}
}
}
위 코드처럼 작성 후에 디버그 창을 열어놓고 런을 해보면 아래와 같은 결과 값을 확인할 수 있습니다.
간단하게 코드로 예제를 들어보겠습니다.
우선 아래와 같이 Text
를 지정해주고 onAppear
로 화면이 로드되면 텍스트가 변경되도록 해주겠습니다.
import SwiftUI
struct OnAppearBootcamp: View {
@State var title: String = "안녕하세요"
var body: some View {
NavigationView {
ScrollView {
Text(title)
}
.onAppear(perform: {
title = "서근개발블로그"
})
.navigationBarTitle("onAppear Bootcamp")
}
}
}
title
을 "안녕하세요" 라고 지정해줬지만 결과 화면을 보면 "서근 개발 블로그"라고 바로 로그가 되죠? 왜냐하면 onAppear
은 특정 뷰가 화면에 나타날 때 지정했던 항목을 바로 보여주기 때문입니다.
이것을 확인해보려면 지연 효과를 주면 되는데 지연 효과를 주는 방법은 DispatchQueue
를 사용하는것입니다.
처음에는 사용하기 어렵겠지만 사용하다보면 쉬운 코드이기 때문에 외우시는 걸 추천드립니다.
DispatchQueue.main.asyncAfter(deadline: .now() + Double) {
//some code
}
struct OnAppearBootcamp: View {
@State var title: String = "안녕하세요"
var body: some View {
NavigationView {
ScrollView {
Text(title)
}
.onAppear(perform: {
DispatchQueue.main.asyncAfter(deadline: .now() + 3){
title = "서근개발블로그"
}
})
.navigationBarTitle("onAppear Bootcamp")
}
}
}
한번 프리뷰를 실행해보겠습니다. 저는 title
이 서근개발블로그 로 바뀌는 데까지 3초의 시간이 걸리도록 해줬습니다. 확인해볼게요.
다른 예를 한번 들어보겠습니다.
화면에 사각형인 도형을 ForEach
로 100개 정도 생성 후에 스크롤을 내릴 때마다 카운트를 시작해 현재 로드가 된 개수는 몇 개인지 나타내려고 합니다.
전 게시글에서도 언급했듯이 화면에 용량이 있는 데이터를 사용할 때는 단순한 Stack
보다는 LazyStack
을 사용하는 것이 좋습니다.
처음에는 VStack
을 사용하고 안에 onAppear
을 추가해 count += 1
을 넣어줘서 카운트가 하나씩 올라가도록 해주겠습니다.
struct OnAppearBootcamp: View {
@State var title: String = "안녕하세요"
@State var count: Int = 0
var body: some View {
NavigationView {
ScrollView {
VStack {
ForEach(0..<100) { _ in
RoundedRectangle(cornerRadius: 20)
.fill(Color.white)
.shadow(radius: 10)
.frame(height: 200)
.onAppear {
count += 1
}
}
.padding()
}
Text(title)
}
.onAppear(perform: {
DispatchQueue.main.asyncAfter(deadline: .now() + 3){
title = "서근개발블로그"
}
})
.navigationBarTitle("로드 된 도형 개수 : \(Int(count))개")
}
}
}
한번 결과하면을 볼까요?
처음 실행했을 때부터 100개가 한 번에 로드가 되었습니다. 하지만 VStack
을 LazyVStack
으로 수정해준다면 어떨까요?
NavigationView {
ScrollView {
LazyVStack {
ForEach(0..<100) { _ in
RoundedRectangle(cornerRadius: 20)
.fill(Color.white)
.shadow(radius: 10)
.frame(height: 200)
.onAppear {
count += 1
}
}
.padding()
}
Text(title)
}
.onAppear(perform: {
DispatchQueue.main.asyncAfter(deadline: .now() + 3){
title = "서근개발블로그"
}
})
.navigationBarTitle("로드 된 도형 개수 : \(Int(count))개")
}
읽어주셔서 감사합니다🤟