SwiftUI

SwiftUI - @State

iosos 2023. 8. 19. 21:06

@State 

- SwiftUI에서 사용되는 프로퍼티 래퍼(wrapper) 중 하나로, 데이터의 변경 사항을 추적하고 뷰를 업데이트하는 데 사용

- 상태 변화에 따라 자동으로 뷰를 갱신하는데 중요한 역할을 수행 

 

- @State로 선언한 변수의 값이 변경되면 SwiftUI는 자동으로 해당 변수가 속한 뷰의 내용을 다시 렌더링하여 화면에 반영

- 뷰와 데이터가 항상 동기화되어 사용자 인터페이스를 갱신하는 데 편리함 제공 

 

 

 

선언 방법

@State private var myValue: DataType = initialValue

 

 


사용 예)

저번 게시물에서 사용했던 코드를 이용하여 @state를 사용하겠음 

참고 →  2023.08.17 - [분류 전체보기] - SwiftUI - 튜토리얼

import SwiftUI

struct Tutorial: View {
    var body: some View {
        
        VStack{
            
            newView()
            newView()
            newView()
            
        } // VStack
        .padding(20)            // 패딩 추가
        .background(.yellow)    // 배경색 노란색 지정 
    }
}

 

 

이 화면에서 탭 제스처를 추가하여 화면 터치 시 padding의 크기를 늘리고 줄이고, 배경색 변경 
버튼을 추가하여 네비게이션 이동까지를 목표로 함

 

 

 

@State 변수 설정

    // @State : 값의 변화를 감지하고 뷰에 적용
    @State private var isActivated : Bool = false

- 뷰를 터치 했을 때 값을 변경하여 뷰를 바로 수정해야 하므로 동기화가 가능한 @State를 사용하여 변수 설정

 

 

 

탭 제스처 설정

        // 탭 제스처 추가
        .onTapGesture {
            
            // toggle() true이면 false로 false면 true로 변경
            self.isActivated.toggle()
        }

- VStack 탭 시 toggle()을 사용하여 true이면 false로 false이면 true로 값 변경 

 

 

 

isActivated 값에 따른 패딩과 배경색 변화

        // isAcitved가 true이면 50, false면 10으로 패딩 지정
        .padding(isActivated ? 50 : 10)
        
        // isAcitved가 true이면 .yellow, false면 .green
        .background(isActivated ? .yellow : .green)

 

 

 

결과 화면)

- 탭을 할 때마다 패딩의 값과 배경색의 변화되는 것을 확인할 수 있다

- 이제 여기에 애니메이션을 추가해보겠다

 

 

 

애니메이션 추가

        // 탭 제스처 추가
        .onTapGesture {
            
            // 애니메이션 추가
            withAnimation{
                
                // toggle() true이면 false로 false면 true로 변경
                self.isActivated.toggle()
            }
        }

- toggle() 될 때를 'withAnimation' 으로 감싸면 애니메이션이 추가 됨 

 

 

 

 

 

NavigationView 추가 

- 탐색 링크, 네비게이션 바, 백 버튼과 같은 기능 자동 제공

- NavigationView 내에서 탐색되는 뷰들은 NavigationLink를 사용하여 구성하며, 사용자 링크를 탭하면 해당 뷰로 자연스럽게 이동함 

 

 var body: some View {
        
        NavigationView{
            VStack{
                VStack{
                    
                    newView()
                    newView()
                    newView()
                    
                } // VStack
                
                // isAcitved가 true이면 50, false면 10으로 패딩 지정
                .padding(isActivated ? 50 : 10)
                
                // isAcitved가 true이면 .yellow, false면 .green
                .background(isActivated ? .yellow : .green)
                
                // 탭 제스처 추가
                .onTapGesture {
                    
                    // 애니메이션 추가
                    withAnimation{
                        
                        // toggle() true이면 false로 false면 true로 변경
                        self.isActivated.toggle()
                    }
                }
                
                // destination : 이동하고자 하는 뷰
                NavigationLink(destination: myTextView()){
                    Text("네비게이션")
                        .fontWeight(.heavy)
                        .font(.system(size:30))
                        .padding()
                        .background(.yellow)
                        .foregroundColor(.white)
                        .cornerRadius(30)
                }
                .padding(30)
                
            }
        }   // NavigationView
    }   // body

- VStack 자체를 NavigationView로 감싸고 아래 화면처럼 밑 "네비게이션" 텍스트의 위치를 고정해주기 위해 VStack을 추가함 

- 'NavigationLink' 를 사용하여 'destination' 에 이동할 뷰를 입력 'myTextView()' 

- 이후 클로저를 사용하여 Text 뷰 추가 

 

 

 

 

myTextView()

- '@State' 로 'index' 변수를 선언하여 'index' 가 변할 때 배경색이 변경되도록 함

// 이동할 뷰
struct myTextView : View{
    
    // 배경색 배열 인덱스
    @State var index = 0
    
    // 배경색 배열
    let backgroundColorArray = [Color.red, Color.blue, Color.green, Color.yellow, Color.brown]
    
    
    var body: some View{
        VStack{
            Text("배경 아이템 인덱스 \(self.index)")
                .font(.system(size: 30))
                .fontWeight(.bold)
            
                // 배경을 전체로 설정
                .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
        }
        .background(self.backgroundColorArray[self.index])
        
        .onTapGesture {
            // index가 backgroundColorArray의 배열 수보다 커지면 index를 0으로 설정
            if (index == backgroundColorArray.count - 1){
                index = 0
            }
            else{
                index += 1
            }
        } // onTopGesture
    }
}

 

 

완성 simulator

 

 

 

 

 

 

참고)

https://www.youtube.com/watch?v=qY9N34mfCjQ&list=PLgOlaPUIbynqyJHiTEv7CFaXd8g5jtogT&index=2 

'SwiftUI' 카테고리의 다른 글

SwiftUI - SwiftUI 모드로 Xcode 이용  (1) 2024.01.07
SwiftUI - 개요  (0) 2024.01.07
SwiftUI - @Binding  (0) 2023.08.25
SwiftUI - 튜토리얼  (0) 2023.08.17
SwiftUI - Container Views (VStack, HStack)  (0) 2023.07.28