SwiftUI

SwiftUI @State, @Binding, TextField

Daesiker 2021. 2. 16. 11:30
반응형

개요

SwiftUI는 뷰 계층을 구성할 때 뷰에 대한 데이터 종속성도 표시한다. 외부 이벤트 또는 사용자가 수행한 작업으로 인해 데이터가 변경되면 SwiftUI는 인터페이스의 영향을 받는 부분을 자동으로 업데이트한다. 이런 앱 모델 내의 데이터 흐름과 변경사항을 제어하고 대응하는 상태를 제공하는 것은 총 3가지가 존재한다.

—State

—Binding

—Observed Object

 

 

 


@State

SwiftUI의 view는 Struct 구조체로 구성되어 있고 이는 언제든 사용가능하고 소멸 또한 가능하다. 일반적으로는 Struct는 값 타입이라 Struct 안에 있는 값을 변경할 수 없다. 그래서 만든 것이 @State 키워드로 이는 struct 내에서 값을 변경가능하도록 도와준다.

 

— String, Int, Bool 같은 간단한 타입에만 사용되는 것이 좋다.

— @State 변수는 private로 선언되고, 다른 view와는 공유되지 않는다.

 

 

Example

import SwiftUI

struct ContentView: View {
    @State var userName: String = ""
    var body: some View {
        VStack {
            TextField("Enter your ID", text: $userName)
                .border(Color(UIColor.separator))
            Text("Welcome, \(userName)!")

        }
        .textFieldStyle(RoundedBorderTextFieldStyle())
        .padding()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

textField의 값이 변하면 Text의 값 상태가 자동으로 변한다.

 

 

→ @State 변수는 struct 구조체의 맨 앞부분의 문자열 userName을 선언한다.

→ $기호를 사용하여 state property를 호출한다.

→ userName의 값이 변하면 userName을 참조하는 컴포넌트가 새로 렌더링되어 값을 표현한다.

 


@Binding

자신의 뷰가 아닌 부모의 뷰에서 값을 가져오고 싶을 때 사용하는 키워드이다. 뷰끼리 양방향으로 연결을 해서 서로 값을 공유할 수 있도록 도와주는 키워드이다.

 

Example

import SwiftUI

struct ContentTextView: View {
    @Binding var message: String
    
    var body: some View {
        Text(message)
            .padding(10)
            .border(Color.orange, width: 1.5)
    }
}

struct ContentView: View {
    @State var userName: String = ""
    var body: some View {
        VStack {
            TextField("Enter your ID", text: $userName)
                .border(Color(UIColor.separator))
            ContentTextView(message: $userName)
        }
        .textFieldStyle(RoundedBorderTextFieldStyle())
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

 

→ View 구조체 안에 Binding 변수를 선언하면 해당 구조체에 파라미터가 생성이 된다.

→ 파라미터안에는 부모 뷰의 state Property를 표시하고 싶은 변수를 넣으면 된다.

→ $ 기호를 넣어서 사용하는 이유는 Binding을 통해 참조만 할 것인지 새로운 값까지 대입할 것인지 판단할 수 없기 때문에 사용한다.

 


TextField

 

import SwiftUI

struct ContentView: View {
    @State var userName: String = ""
    var body: some View {
        TextField("Enter Username...",
                  text: $userName,
                  onEditingChanged: { _ in print("changed")},
                  onCommit: {print("commit")}
        )
        .textFieldStyle(RoundedBorderTextFieldStyle())
        .border(Color.orange, width: 2.0)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

→ TextField의 첫번째 파라미터는 placeholder이다. 파라미터명 없이 String 값을 넣어주면 placeholder가 생성된다.

→ text : TextField에 텍스트가 입력되면 입력정보가 저장되는 변수를 집어넣는 곳이다. @State로 선언된 변수를 넣어주면, 텍스트가 입력된다.

→ onEditingChanged : TextField는 사용자가 텍스트를 편집하거나 완료할 때 마다 onEditingChnaged 클로저를 호출한다. 시작이나 종료하는 시점을 알려주는 bool 값을 전달하여서 시작, 종료 시점에 특정 이벤트를 호출하고 싶으면 여기 안에 이벤트를 넣으면 된다.

→ onCommit : 사용자가 textField안에 값을 입력하고 return 키를 누를 때 호출하는 부분이다.

 

→ .textFieldStyle : TextField안에 스타일을 적용하고 싶을 때 사용한다.

→ border : 테두리를 꾸밀 때 사용한다. color와 두께를 설정할 수 있다.

 

Formatter

import SwiftUI

extension NumberFormatter {
    static var currency: NumberFormatter {
        let formatter = NumberFormatter()
        formatter.numberStyle = .currency
        return formatter
    }
}

struct ContentView: View {
    @State private var price = 100
    var body: some View {
        TextField("type something...",
                  value: $price,
                  formatter: NumberFormatter.currency)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

TextField에서는 formatter을 통해 원시 값을 Formatter가 변환을 하여 새로운 값으로 만드는데 이때 사용하는 파라미터는 value와 formatter이다.

value에 textField에 입력하는 값을 대입하고, formatter에 원하는 형식을 입력하면 해당 formatter에 맞게 데이터가 변형되어 보여진다.

❗formatter가 바꿀 수 없는 형식의 데이터가 입력되면 원시값을 그대로 전달한다.

 

Secure TextField

 

SecureField("Enter the password", text: $password)

SecureField 키워드를 사용하면 비밀번호 입력 창처럼 텍스트가 보이지 않는 컴포넌트를 만들 수 있다. TextField와 사용법이 비슷하

반응형