뷰 상태변경 제 1장

2024. 11. 13. 15:02·iOS 개발/SwiftUI

오늘의 내용은?

앞에서 Property Wrapper에 관하여 포스팅을 하였습니다. Property Wrapper는 프로퍼티에 미리 정의해둔 연산을 통해서 값을 관리할 수 있도록 도와줍니다. 오늘은 Property Wrapper가 개발에서 실제로 어떻게 쓰이는지 확인해보도록 하겠습니다.

@State

SwiftUI에서 상태변경를 위에서 자주 쓰이는 property wrapper중 하나인데 공식문서에서는 아래와 같이 정의가 되어있습니다.

  • SwiftUI에서 값을 관리하고 읽고 쓸 수 있는 property wrapper입니다.

  • @State 속성은 속성 선언에 상태를 추가하고 초기값을 설정할 때 사용됩니다.
  • @State로 선언된 속성을 private로 선언하면 memberwise initializer(구조체가 가지는 모든 속성을 초기화하는 기본 생성자)에서 이 속성을 설정하는 것을 방지할 수 있습니다.
  • 상태는 뷰 계층에서 가장 높은 뷰에 private으로 선언하여 상태에 접근해야 하는 뷰에만 접근을 허용하는 것이 좋습니다.
  • 하위 뷰에서도 접근이 필요할 경우 바인딩을 사용하여 안전하게 접근할 수 있습니다.
  • 상태 속성은 어떤 스레드에서도 안전하게 변경될 수 있습니다.

🤔내용을 보면 뷰 값을 관리한다, private로 선언하는 것이 좋다, 하위 뷰에서도 접근이 가능하다. 라고 되어있고 살을 덧붙여서 정리를 해보았습니다.

@State는 뷰에서 상태의 값을 관리하며 뷰의 상태 변화를 감지하고 변경될 때 마다 해당 뷰를 다시 그리도록 합니다. 특히나 하위 뷰에서 접근이 가능합니다.

@State 예시

숫자 증가 및 감소 버튼을 구현하여 실시간으로 UI에 숫자가 변경되는 것으로 예시를 들어보겠습니다.

  • @State를 사용하여 초기 숫자 변수 number를 정의하였습니다. @State는 SwiftUI에서 상태를 관리하는 속성으로, 값이 변경될 때 뷰가 다시 렌더링됩니다.
  • “숫자 감소” 버튼을 클릭하면 number 값이 1씩 감소하도록 정의되었고, “숫자 증가” 버튼은 그 반대로 1씩 증가하는 동작을 하도록 설정하였습니다.

영상을 통해 각 버튼을 클릭할 때마다 number 값이 즉시 변경되고, 이 변경 사항이 UI에 반영되어 뷰가 실시간으로 업데이트되는 것을 확인할 수 있습니다. @State 덕분에 버튼 액션에 따라 UI가 자동으로 다시 그려지게 됩니다.

import SwiftUI

struct StateEx: View {
    @State private var number: Int64 = 0
    
    var body: some View {
        VStack(spacing: 20) {
            Text("\\(number)")
                .font(.largeTitle)
            
            HStack(spacing: 30) {
                Button(action: {
                    number -= 1
                }, label: {
                    Text("숫자 감소")
                })
                
                Button(action: {
                    number += 1
                }, label: {
                    Text("숫자 증가")
                })
            }
            
        }
    }
}

#Preview {
    StateEx()
}

 

 


@Binding

State로 정의한 값을 하나의 뷰에서만 사용하기에는 아쉽잖아요? 하위 뷰에서는 Binding이라는 property wrapper를 통해 값을 사용할 수 있습니다.

  • 데이터를 소유한 원본 값에 대해 읽고 쓸 수 있는 property wrapper 유형입니다.

  • 바인딩을 사용하여 데이터를 저장하는 속성과 데이터를 표시하고 변경하는 뷰 간에 양방향 연결을 생성할 수 있습니다.
  • 바인딩은 데이터를 직접 저장하는 대신 다른 곳에 저장된 “source of truth“로부터 속성을 연결합니다.

@Binding은 데이터의 원천을 참조하며 직접 값을 수정하고 사용 가능하게 만들어 줍니다.

@Binding 예시

두개의 뷰에서 @Binding을 활용하여 하나의 값을 참조하여 숫자 값을 수정하는 예시입니다.

  • 상위 뷰에서 number 변수를 @State로 정의하여 상태를 관리하고, 이를 하위 뷰에서 참조할 수 있도록 하였습니다.
  • sheet가 활성화될지를 제어하기 위해 subviewToggle이라는 @State 변수를 사용하여 뷰의 표시 여부를 관리합니다.
  • “숫자 수정하기” 버튼을 클릭하면 subviewToggle의 값이 반전(false에서 true 또는 그 반대)되며, 이 값에 따라 sheet가 나타나거나 사라지게 됩니다.
  • sheet는 isPresented라는 감시자에 subviewToggle의 값이 true로 반환될 때 sheet를 나타나게 해줍니다.
    • 이때 sheet를 통해 보여지는 하위 뷰에서는 상위 뷰의 값을 사용하기 위해 @Binding을 정의하였으며, 이를 $number와 함께 연결하여 넘겨줍니다.

BindingExSubView는 @Binding을 통해 상위 뷰의 number 값과 연결되어 있으므로, 하위 뷰에서 숫자를 변경하면 그 변경 사항이 상위 뷰에도 적용됩니다. 이를 통해 두 뷰 간의 값이 실시간으로 동기화됩니다. 영상으로 이제 결과를 확인해 보세요!

import SwiftUI

struct BindingEx: View {
    @State var number: Int64 = 0
    @State var subviewToggle: Bool = false
    
    var body: some View {
        Text("\\(number)")
            .font(.largeTitle)
        
        Button(action: {
            subviewToggle.toggle()
        }, label: {
            Text("숫자 수정하기")
        })
        .sheet(isPresented: $subviewToggle, content: {
            BindingExSubView(number: $number)
        })
        .padding()
    }
}

struct BindingExSubView: View {
    @Binding var number: Int64
    var body: some View {
        VStack(spacing: 20) {
            Text("\\(number)")
                .font(.largeTitle)
            
            HStack(spacing: 30) {
                Button(action: {
                    number -= 1
                }, label: {
                    Text("숫자 감소")
                })
                
                Button(action: {
                    number += 1
                }, label: {
                    Text("숫자 증가")
                })
            }
            
        }
    }
}

#Preview {
    BindingEx()
}

 

 

 

State와 Binding을 통해서 뷰 간에 데이터를 손 쉽게 사용할 수 있고 관리할 수 있게 됩니다.

이렇게 오늘은 뷰 상태변경을 정리해보았습니다. 다음 내용은 뷰 상태변경 제2장의 내용을 정리 해볼려고 합니다! 부족한 내용이지만 끝까지 읽어봐주셔서 감사합니다. 지인에게 추천받은 개발자 속담으로 마무리하도록 하겠습니다! 파이팅입니다~

“안되는 것은 없다. 다만 시간이 조금 필요하거나 조금 더 필요할 뿐”

'iOS 개발 > SwiftUI' 카테고리의 다른 글

[SwiftUI] @Published 썼는데도 View가 안 바뀐다?  (0) 2025.05.30
[SwiftUI] Splash & Onboarding 화면 구현 리뷰 (Feat. 나만의 Todo)  (1) 2025.05.26
[SwiftUI] Figma 비율 그대로! 개발하는 Constants 구조체 만들기  (1) 2025.05.24
뷰 상태변경 제 2장  (8) 2024.11.13
Property Wrapper  (2) 2024.09.22
'iOS 개발/SwiftUI' 카테고리의 다른 글
  • [SwiftUI] Splash & Onboarding 화면 구현 리뷰 (Feat. 나만의 Todo)
  • [SwiftUI] Figma 비율 그대로! 개발하는 Constants 구조체 만들기
  • 뷰 상태변경 제 2장
  • Property Wrapper
Riu
Riu
안녕하세요 iOS 개발자를 꿈꾸는 Riu입니다. Github: woolnd
  • Riu
    Riu 개발노트
    Riu
  • 전체
    오늘
    어제
    • 분류 전체보기 (27) N
      • 티스토리 (2)
      • iOS 개발 (21) N
        • SwiftUI (9)
        • UIKit (6)
        • Combine (5)
        • Architecture (1) N
      • 알고리즘 (1)
      • 회고록 (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • Github
  • 공지사항

  • 인기 글

  • 태그

    UIKit
    막자알림서비스
    ios개발
    티스토리
    회고록
    Architecture
    SWIF
    SWIFT
    안드로이드
    알고리즘
    나만의todo
    앗차!
    Combine
    SwiftUI
    cleanArchitecture
    구름톤유니브
    ios
    figma
    시작
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
Riu
뷰 상태변경 제 1장
상단으로

티스토리툴바