iOS SwiftUI


2023.03.09 – (앱 개발/iOS) – iOS SwiftUI의 @State 구문을 어떻게 사용할 수 있나요?

@제본

바인딩을 사용하여 데이터를 저장하는 속성과 데이터를 표시하고 수정하는 보기 간에 양방향 연결을 만듭니다.

데이터를 직접 저장하는 대신 바인딩은 속성을 다른 곳에 저장된 정보 소스에 연결합니다.

예를 들어 재생과 일시중지 사이를 전환하는 버튼 Bindingproperty 래퍼를 사용하여 상위 보기의 속성에 대한 바인딩을 만들 수 있습니다.

ContentView의 기본 드로잉인 CircleImageView에 대한 바인딩을 사용하겠습니다.

 //데이터 연동
    @Binding
    var isActivated : Bool
    
    //생성자
    init(isActivated: Binding<Bool> = .constant(false)) {
        _isActivated = isActivated
    }

(핵심 코드입니다.

) 변수를 선언하고 변수의 상수(기본값)를 설정하는 생성자를 작성합니다.

다른 보기 페이지에서 받은 값을 인수로 받아 조합합니다.

import SwiftUI

struct CircleImageView : View{
    
    @Binding
    var isActivated : Bool
    
    init(isActivated: Binding<Bool> = .constant(false)) {
        _isActivated = isActivated
    }
    
    
    
    var body: some View{
        //        Image(systemName: "bolt.circle")
        //            .font(.system(size: 200))
        //            .foregroundColor(.yellow)
        //            .shadow(color: .gray, radius: 2, x: 0, y:10)
        Image("myimage").resizable()
            .scaledToFill()
//            .aspectRatio(contentMode: .fill)
            .frame(width: 200, height: 200)
            .clipShape(Circle())
            // color는 항상 맨 앞으로 !
.shadow(color: .black ,radius: 10,x:0,y:10) .overlay(Circle().foregroundColor(.black).opacity(0.4)) .overlay(Circle().stroke(Color.red,lineWidth: 10).padding()) .overlay(Circle().stroke(Color.yellow,lineWidth: 10).padding(30)) .overlay(Circle().stroke(self.isActivated ? Color.green : Color.blue ,lineWidth: 10).padding(self.isActivated ? 0 : 45 )) .overlay(Text("Joonho").foregroundColor(.white).font(.system(size: 30)).fontWeight(.bold)) // .clipped() // .edgesIgnoringSafeArea(.all) } } struct Previews_CircleimageView_Previews: PreviewProvider { static var previews: some View { CircleImageView() } }

.overlay(Circle().stroke) 코드에서 삼항 연산자를 사용하여 값으로 이미지를 변경했습니다.

반응형


import SwiftUI

struct MyTextView:View {
    
        // 데이터 연동
        @Binding
        var isActivated: Bool
        
        // 생성자
        init(isActivated: Binding<Bool> = .constant(false)) {
            _isActivated = isActivated
        }
    
    
    //state : 값의 변화를 감지 -> 뷰에 적용
    @State
    private var index : Int = 0
    
    //배경색 배열 준비
    private let backgroubdColors = (
        Color.red,
        Color.yellow,
        Color.blue,
        Color.green,
        Color.orange
    )
    
    
    var body : some View {
        VStack{
            Spacer()
            
            Text("배경 아이템 인덱스 \(self.index + 1 )")
                .font(.system(size: 30))
                .fontWeight(.bold)
                .frame(minWidth: 0,maxWidth: .infinity,
                       minHeight: 0, maxHeight: 100)
            HStack{
                Text("활성화 상태")
                    .font(.system(size: 30))
                    .foregroundColor(Color.white)
                    .fontWeight(.bold)
                    .background(Color.black)
                    
                Text("\(String(isActivated))")
                    .font(.system(size: 30))
                    .fontWeight(.bold)
                    .foregroundColor(self.isActivated ? Color.green : Color.red)
                    .background(Color.black)
            }
            
            Spacer()
            
        }
        .background(backgroubdColors(index))
        .edgesIgnoringSafeArea(.all)
        .onTapGesture {
            print("배경아이템이 클릭되었다.

") if(self.index == self.backgroubdColors.count - 1){ self.index = 0 }else{ self.index += 1 } } } struct Previews_MyTextView_Previews: PreviewProvider { static var previews: some View { MyTextView() } } }

이 페이지에서 페이지 화면에 데이터 값을 출력해 보았습니다.

import SwiftUI

struct ContentView: View {
    // @State 값의 변화를 감지 -> 뷰에 적용
    @State
    private var isActivated : Bool = false
    
    var body: some View {
        
       
            NavigationView{
                VStack{
                    HStack{
//                        MyVstackView()
//                        MyVstackView()
                        CircleImageView(isActivated: $isActivated)
                        
                        
                    }
                    .padding(isActivated ? 100.0 :50.0)
                    .background(isActivated ? Color.black : Color.indigo)
                    .cornerRadius(isActivated ? 0 : 20) 
                    // 탭 제스쳐 추가
                    .onTapGesture {
                            print("HStack 클릭 되었다.

") //에니메이션과 함께 withAnimation{ // toggle() true 이면 false 로 false 이면 true self.isActivated.toggle() } }// Hstack // 네비게이션 버튼 (링크) NavigationLink(destination:MyTextView(isActivated: $isActivated)){ Text("Navigation") .fontWeight(.bold) .padding() .font(.system(size: 40)) .background(Color.green) .foregroundColor(Color.white) .cornerRadius(30) }.padding(.top,50) } }//NavigationView } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }

결국 다른 페이지의 @Binding 값은 ContentView의 @State private var isActivated와 연결된 데이터라고 생각하시면 됩니다.

해당 값을 다른 뷰로 보낼 때 CircleImageView(메인 뷰의 변수명: $Related view Binding 변수명)

그냥 꽂으세요.