카테고리 없음

@FocusState: SwiftUI에서 포커스 관리하는 방법

ragdoll-cat 2025. 2. 12. 23:39

SwiftUI에서 FocusState는 텍스트 필드와 같은 입력 요소의 포커스를 관리하는 데 사용되는 프로퍼티 래퍼입니다. @FocusState를 사용하면 특정 필드가 포커스를 가졌는지 여부를 바인딩하여 제어할 수 있습니다.

기본 사용 방법

다음은 FocusState를 활용하여 텍스트 필드의 포커스를 관리하는 간단한 예제입니다.

import SwiftUI

struct FocusStateExampleView: View {
    @FocusState private var isFocused: Bool
    @State private var text: String = ""
    
    var body: some View {
        VStack {
            TextField("Enter text", text: $text)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .focused($isFocused)
                .padding()
            
            Button("Toggle Focus") {
                isFocused.toggle()
            }
        }
    }
}

 

 

  • @FocusState private var isFocused: Bool 포커스를 관리할 변수를 선언합니다.
  • focused(_:) 수정자를 사용하여 TextField의 포커스를 isFocused 바인딩과 연결합니다.
  • isFocused 값을 변경하면 포커스가 토글됩니다.

Enum을 활용한 포커스 관리

여러 개의 입력 필드가 있을 경우, Bool 타입 대신 enum을 활용하여 개별 필드의 포커스를 제어할 수 있습니다.

import SwiftUI

struct MultiFieldFocusView: View {
    enum FocusField: Hashable {
        case firstName, lastName
    }
    
    @FocusState private var focusedField: FocusField?
    @State private var firstName: String = ""
    @State private var lastName: String = ""
    
    var body: some View {
        VStack {
            TextField("First Name", text: $firstName)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .focused($focusedField, equals: .firstName)
                .padding()
            
            TextField("Last Name", text: $lastName)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .focused($focusedField, equals: .lastName)
                .padding()
            
            Button("Next") {
                if focusedField == .firstName {
                    focusedField = .lastName
                } else {
                    focusedField = nil
                }
            }
        }
    }
}

 

  • Hashable을 채택한 열거형을 정의합니다.
  • @FocusState private var focusedField: FocusField?를 선언하여 특정 필드에 대한 포커스 상태를 저장할 변수를 생성합니다.
  • .focused($focusedField, equals: .firstName)와 같이 특정 필드와 바인딩합니다.
  • focusedField가 .firstName과 같을 때 위의 TextField가 포커스를 갖게 됩니다.

유의사항

  1. @FocusState는 iOS 15 이상에서 사용 가능
    • @FocusState는 iOS 15 이상에서 지원되므로, 하위 버전 지원이 필요한 경우 다른 방식(예: onAppear에서 UITextField 활용)으로 구현해야 합니다!
  2. isFocused = false를 설정하면 키보드가 내려감
    • @FocusState false로 설정하면 키보드가 자동으로 사라진다.
  3. 필요에 따라 DispatchQueue.main.async 활용
    • NavigationView 내부에서 @FocusState를 사용하면 onAppear 시 자동으로 포커스가 설정되지 않는 경우가 있습니다. 이 경우 DispatchQueue.main.async를 사용하면 해결할 수 있습니다.
    TextField("Enter text", text: $text)
        .focused($isFocused)
        .onAppear {
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                isFocused = true
            }
        }

 결론

  • @FocusState는 SwiftUI에서 포커스를 쉽게 제어할 수 있는 강력한 도구입니다.
  • 단일 필드의 포커스는 Bool, 여러 필드의 포커스는 enum을 활용하면 관리가 용이합니다.
  • 특정 상황에서 포커스가 예상대로 작동하지 않을 수 있으므로, 적절한 DispatchQueue 사용이 필요할 수 있습니다.