[SwiftUI] onChange 역할을 알아보자

오늘은 SwiftUI 에서 자주 만나게 되는 onChange에 대해서 알아보는 시간을 가져보자

https://developer.apple.com/documentation/swiftui/view/onchange(of:perform:)

먼저 onChange는 뷰의 특정 값이 변경될 때 동작을 수행할 수 있게 해주는 도구라고 보는 편이 이해하기 쉽다 🙂

 

onChange를 통해 상태 변화에 반응하고 다른 효과를 실행하거나 상태를 업데이트하는 등 다양한 방면에 사용된다. 예를 들어 사용자의 입력이 변화할때 UI를 업데이트하거나 특정 동작을 수행하는데 사용할 수 있다.

.onChange(of: value, perform: { newValue in
    // 'value'가 변경되었을 때 실행할 코드
})

기본적인 사용 문법은 이렇게 된다. value는 감지하고 싶은 값을 설정하고 State, Binding 등 어떤 값도 사용할 수 있다.

 

newValue는 value가 변경된 후의 새로운 값이다. 이 값은 클로저의 형태로 전달되고 변경된 값에 따라 작업을 수행할 수 있다.

 

이정도로 간단한 정의에 대해서 알아보고 텍스트필드의 입력값 변화에 따라 작업을 수행하는 예제를 가지고 더 알아보도록 하자

import SwiftUI

struct OnChangeExampleView: View {
    @State private var username: String = ""

    var body: some View {
        VStack {
            TextField("사용자 이름을 입력하세요", text: $username)
                .padding()
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .onChange(of: username) { newValue in
                    print("사용자 이름이 변경되었습니다: \\(newValue)")
                }

            Text("현재 사용자 이름: \\(username)")
                .padding()
        }
        .padding()
    }
}

현재 username 상태 변수에 TextField가 바인딩 되어 있다. 그 다음 onChange를 통해 새로운 값 즉 텍스트필드 내 값이 변경되면 onChange를 통해 내부 클로저가 실행되어 콘솔에 새로운 값을 출력하는 형태이다.

 

이처럼 텍스트필드의 값 변화를 감지하고 이를 핸들링 할 수 있게 해주는 역할을 한다.

 

다음은 부모뷰에 전달된 바인딩 값의 변화를 감지하는 예제를 살펴보자

import SwiftUI

struct ParentView: View {
    @State private var isToggled: Bool = false

    var body: some View {
        VStack {
            Toggle("토글 스위치", isOn: $isToggled)
                .padding()

            ChildView(isToggled: $isToggled)
        }
        .padding()
    }
}

struct ChildView: View {
    @Binding var isToggled: Bool

    var body: some View {
        Text(isToggled ? "스위치가 켜짐" : "스위치가 꺼짐")
            .padding()
            .onChange(of: isToggled) { newValue in
                print("ChildView에서 감지된 변경 사항: isToggled = \\(newValue)")
            }
    }
}

현재 ParentView는 isToggled 상태변수를 가지고 있고 isOn에 이를 바인딩하고 있다.

 

ChildView는 이 상태 변수를 바인딩으로 받아와 UI를 업데이트하는 형태의 예제이다!

 

ChildView에서 onChange(of:) 를 사용해 isToggled 값의 변화를 감지하고 그 변화가 감지 될 때마다 콘솔에 메세지를 출력한다.

 

이처럼 onChange는 다른뷰에서 값의 변화를 감지하고 그 값을 처리해줄 수 있다.

위에 예제에서는 다루지 않았지만 일반적으로 언제 사용되냐면

  • 상태 변화에 따라 UI를 업데이트 할 때
  • 값의 변화를 로깅하거나 디버깅 할 때
  • 네트워크 요청이나 다른 부가적인 작업을 상태 변화에 따라 실행할 때
  • 모델이나 외부 데이터 소스와 UI를 동기화 할 때

주의할 점은 메인스레드에서 실행되기 때문에 UI 구성에 영향이 갈만한 긴 프로세스 실행은 하지 않는 편이 좋다!!

만약 값 변경에 대한 응답으로 긴 프로세스가 실행되어야 한다면, 백그라운드로 Dispatch해서 처리하는 방식이 필요하다.

 

이처럼 다양하고 활용성 높게 사용되는 onChange를 알아 보았다! SwiftUI로 작업하면서 상당히 자주 만나보게 되기 때문에 꼭 숙지하고 이해하도록 하자!