본문 바로가기

Programming/Swift

[SwiftUI] @FocusState Property Wrapper

반응형

iOS 15에 추가된 FocusState Property Wrapper입니다.

Focus를 자유롭게 이동시키기 위한 Property Wrapper이며

아래와 같이 선언해서 사용합니다.

@FocusState var isFocusField: Bool
@State var email: String

UITextField("email", text: $email, prompt: Text("email"))
	.focus($isFocusField)


만약 포커스할 입력창 여러개 있어야 할 경우, 이렇게 각 필드마다 FocusState를 줘야하는데요

@FocusState var isFocusEmail: Bool
@State var email: String

@FocusState var isFocusPassword: Bool
@State var password: String

UITextField("email", text: $email, prompt: Text("email"))
	.focus($isFocusEmail)
UITextField("password", text: $password, prompt: Text("password"))
	.focus($isFocusPassword)

SwiftUI에서는 이러한 경우에

enum을 통해 다중으로 Focus를 지정해야하는 경우 선언 가능하도록 제공해주고 있습니다.

enum FocusableField: Hashable {
    case email
    case password
}

@FocusState var focus: FocusableField?

TextField(email, text: $email, prompt: Text("email"))
	.focused($focus, equals: .email)
TextField(password, text: $password, prompt: Text("password"))
	.focused($focus, equals: .password)

 

너무나도 편리한 기능이 아닐 수 없는데요

 

FocusState가 필요한 곳은 아마도 회원가입이나 로그인 처럼

요청한 필드를 모두 입력해야지만 다음 스텝으로 넘어갈 수 있는 화면에서 주로 쓰일 것 같습니다.

 

위 케이스에 대한 간략한 예제입니다.

enum FocusableField: Hashable {
    case email
    case password
}

struct ContentView: View {
    @State private var email: String = ""
    @State private var password: String = ""
    @FocusState var focus: FocusableField?
    @State private var showingAlert = false
    
    var body: some View {
        Form {
            TextField(email, text: $email, prompt: Text("email"))
                .focused($focus, equals: .email)
            SecureField(password, text: $password, prompt: Text("password"))
                .focused($focus, equals: .password)
            
            Button("Login") {
                if email.isEmpty {
                    focus = .email
                    return
                }
                
                if password.isEmpty {
                    focus = .password
                    return
                }
                
                showing = true
            }
            .alert("로그인 성공", isPresented: $showingAlert, actions: {
                Button("OK", role: .none) {
                    
                }
            })
        }
        .navigationTitle("Sign In")
        .onAppear {
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                self.focus = .email
            }
        }
    }
}

 

 

출처: https://swiftwithmajid.com/2021/08/24/mastering-focusstate-property-wrapper-in-swiftui/

반응형