SwiftUI의 onChange

June·2023년 2월 23일
0

SwiftUI-Data

목록 보기
8/12
post-thumbnail

onChange

  • View에서 일부 코드를 실행할 수 있게 해주는 view modifier, 앱에서 추가 작업 트리거하는 이벤트로 사용.
  • 필요시 UI를 업데이트함.
  • 속성 값의 변경 사항 관찰을 위해 사용하는 방법.
  • 메인 스레드에서 실행됨. 따라서 UI에 영향이 갈만한 긴 프로세스 실행(서버와의 통신 등)은 금지.
  • 값 변경에 대한 응답으로 긴 프로세스 실행 시, 백그라운드 큐로 Dispatch 해야 함.
  • 이전 값을 캡쳐함.

사용방법

import SwiftUI

struct WhatIsOnChange: View {
    
    @State private var vehicle = "airplane"
    @State private var color = Color.blue
    @State private var icon = "airplane"
    
    var body: some View {
        VStack(spacing: 15) {
            Text("onChange")
                .font(.title)
            
            Text("저장된 값의**텍스트** 변경에 맞춰 코드를 실행한다.")
                .font(.headline)
            
            Button("변경하기") {
                if vehicle == "airplane" {
                    vehicle = "car"
                } else {
                    vehicle = "airplane"
                }
            }
            
            Label(vehicle, systemImage: icon)
                .padding()
                .foregroundColor(.white)
                .background(color, in: RoundedRectangle(cornerRadius: 12))
        }
        // newValue값이 클로저로 전달됨 
        .onChange(of: vehicle) { newValue in
            if newValue == "car" {
                icon = "car"
                color = Color.red
            } else {
                icon = "airplane"
                color = Color.blue
            }
        }
    }
}

이전 값, 새로운 값

struct WhatIsOnChange: View {
    @State private var rotation = Angle.degrees(0)
    @State private var size: CGFloat = 50
    @State private var color = Color.green
    
    var body: some View {
        VStack(spacing: 15) {
            Text("onChange")
                .font(.title)
            
            Text("변경 중인 속성의 이전 값 캡쳐.")
                .font(.headline)
            
            HStack {
                Button("초기화") { rotation = Angle.degrees(0) }
                Spacer()
                Button("회전하기") { rotation = Angle.degrees(90) }
            }
            .padding()
            
            Spacer()
            
            Image(systemName: "rotate.right")
                .rotationEffect(rotation)
                .font(.system(size: size))
                .foregroundColor(color)
                .animation(.default, value: rotation)
            
            Spacer()
        }
        .onChange(of: rotation) { [rotation] newValue in
            if rotation == newValue { return }  // 이전 값이 새 값과 같으면 바로 리턴 
            if newValue == Angle.degrees(0) {
                size = 50
                color = Color.green
            } else {
                size = 100
                color = Color.red
            }
        }
    }
}

변경 사항을 관찰하는 속성의 이전 값과 새 값을 모두 알아야 하는 경우.

  • 이전 값 = rotation
  • 새 값 = newValue
  • 새 값(newValue) 이름은 원하는 대로 지정 가능
  • self 키워드를 이용해 클로저 내에서 실제 속성에 액세스 가능
profile
안다고 착각하지 말기

0개의 댓글