@FocusState SwiftUI में एक property wrapper है, जो iOS 15 में पेश किया गया, जो आपको टेक्स्ट फ़ील्ड और अन्य तत्वों पर इनपुट फ़ोकस को प्रोग्रामेटिक रूप से नियंत्रित करने की अनुमति देता है। इसके आने से पहले, डेवलपर्स को UIKit विधियों becomeFirstResponder और resignFirstResponder तक पहुँचने के लिए UIViewRepresentable का उपयोग करना पड़ता था। @FocusState इस समस्या को मूल रूप से हल करता है: आप .focused() मॉडिफ़ायर के माध्यम से एक प्रॉपर्टी को फ़ील्ड से बाँधते हैं, जिसके बाद फ़ोकस सेट करना या हटाना एक सरल मान असाइनमेंट से होता है। Apple Developer Documentation — FocusState (2025) के अनुसार, @FocusState दो मोड का समर्थन करता है: सरल प्रबंधन के लिए Bool (फ़ोकस चालू या बंद) और कई फ़ील्ड के लिए enum, जहाँ प्रत्येक case एक विशिष्ट इनपुट फ़ील्ड से मेल खाता है।
मुख्य बातें
@FocusState एक property wrapper है जो फ़ोकस स्थिति को SwiftUI में एक विशिष्ट इनपुट फ़ील्ड या अन्य फ़ोकसेबल तत्व से बाँधता है। UIKit के विपरीत, जहाँ फ़ोकस प्रबंधन becomeFirstResponder और resignFirstResponder विधियों के माध्यम से होता है, SwiftUI एक घोषणात्मक दृष्टिकोण का उपयोग करता है: आप एक स्थिति (@FocusState) घोषित करते हैं और इसे .focused() मॉडिफ़ायर के माध्यम से एक तत्व से बाँधते हैं। स्थिति बदलने से फ़ोकस स्वचालित रूप से बदल जाता है।
iOS 15 में @FocusState के आने से पहले, डेवलपर्स को UITextField के आसपास UIViewRepresentable रैपर बनाने या तीसरे पक्ष की लाइब्रेरी का उपयोग करना पड़ता था। @FocusState सीधे SwiftUI में एकीकृत है और TextField, TextEditor, SecureField और SearchField के साथ काम करता है। यह कोड को साफ़ बनाता है, UIKit ब्रिज की संख्या कम करता है और परीक्षण क्षमता में सुधार करता है।
WWDC Session 10136 — What's new in SwiftUI (2024) के अनुसार, @FocusState तत्वों के बीच फ़ोकस जानकारी पास करने के लिए SwiftUI की preference key प्रणाली का उपयोग करता है। जब कोई फ़ील्ड फ़ोकस प्राप्त करता है, SwiftUI स्वचालित रूप से संबंधित @FocusState प्रॉपर्टी को अपडेट करता है, जिससे आप कोड में फ़ोकस परिवर्तनों पर प्रतिक्रिया कर सकते हैं।
@FocusState का उपयोग करने का सबसे सरल तरीका Bool प्रकार के साथ है। जब कोई फ़ील्ड फ़ोकस में होती है, तो प्रॉपर्टी true होती है। जब फ़ोकस चला जाता है — false। आप इसे true पर सेट करके फ़ोकस को बाध्य कर सकते हैं, या इसे false पर सेट करके हटा सकते हैं।
struct LoginForm: View {
@State var email = ""
@FocusState var isEmailFocused: Bool
var body: some View {
VStack {
TextField("Email", text: $email)
.focused($isEmailFocused)
Button("कीबोर्ड दिखाएँ") {
isEmailFocused = true
}
Button("कीबोर्ड छिपाएँ") {
isEmailFocused = false
}
}
}
}
इस उदाहरण में, isEmailFocused स्वचालित रूप से true हो जाता है जब उपयोगकर्ता टेक्स्ट फ़ील्ड पर टैप करता है, और कीबोर्ड छिपने पर false हो जाता है। बटन आपको प्रोग्रामेटिक रूप से फ़ोकस प्रबंधित करने की अनुमति देते हैं — कस्टम कीबोर्ड, "अगला" बटन और उन स्थितियों के लिए उपयोगी जहाँ आपको फ़ॉर्म सबमिशन के बाद कीबोर्ड को बलपूर्वक छिपाने की आवश्यकता होती है।
कई फ़ील्ड वाले फ़ॉर्म के लिए, @FocusState FocusStateValue (या Hashable) प्रोटोकॉल के अनुरूप enum का समर्थन करता है। प्रत्येक enum case एक विशिष्ट फ़ील्ड से मेल खाता है। यह फ़ील्ड के बीच फ़ोकस स्विच करने की अनुमति देता है — उदाहरण के लिए, जब उपयोगकर्ता अगले फ़ील्ड पर जाने के लिए कीबोर्ड पर "अगला" दबाता है।
struct RegistrationForm: View {
enum Field: Hashable {
case email
case password
case confirmPassword
}
@State var email = ""
@State var password = ""
@State var confirmPassword = ""
@FocusState var focusedField: Field?
var body: some View {
Form {
TextField("Email", text: $email)
.focused($focusedField, equals: .email)
.onSubmit { focusedField = .password }
SecureField("Password", text: $password)
.focused($focusedField, equals: .password)
.onSubmit { focusedField = .confirmPassword }
SecureField("Confirm", text: $confirmPassword)
.focused($focusedField, equals: .confirmPassword)
.onSubmit { submitForm() }
}
}
}
.onSubmit मॉडिफ़ायर पर ध्यान दें — यह तब कॉल किया जाता है जब उपयोगकर्ता कीबोर्ड पर "Return" दबाता है। .onSubmit के अंदर हम focusedField को अगले फ़ील्ड पर स्विच करते हैं, जो स्वचालित रूप से फ़ोकस स्थानांतरित करता है। अंतिम फ़ील्ड फ़ॉर्म सबमिट करने के लिए submitForm() को कॉल करता है।
@FocusState कीबोर्ड छिपाने का एक सरल तरीका प्रदान करता है — बस प्रॉपर्टी को nil (enum के लिए) या false (Bool के लिए) पर सेट करें। हालाँकि, कभी-कभी आपको कीबोर्ड को किसी विशिष्ट फ़ील्ड से बाँधे बिना छिपाने की आवश्यकता होती है — उदाहरण के लिए, खाली जगह पर टैप करते समय। इस मामले में, कई दृष्टिकोण हैं।
struct DismissKeyboardView: View {
@State var text = ""
@FocusState var isFocused: Bool
var body: some View {
TextField("Enter text", text: $text)
.focused($isFocused)
.toolbar {
ToolbarItemGroup(placement: .keyboard) {
Spacer()
Button("पूर्ण") {
isFocused = false
}
}
}
}
}
placement .keyboard के साथ .toolbar मॉडिफ़ायर कीबोर्ड के ऊपर एक बटन जोड़ता है। कीबोर्ड छिपाने के लिए iOS में यह एक मानक UX पैटर्न है। एक वैकल्पिक दृष्टिकोण पृष्ठभूमि पर टैप करने पर फ़ोकस रीसेट करने के लिए रूट VStack पर .onTapGesture का उपयोग करना है।
@FocusState फ़ॉर्म सत्यापन के साथ पूरी तरह से संयोजित होता है। एक विशिष्ट पैटर्न: "सबमिट" बटन दबाने के बाद, सभी फ़ील्ड सत्यापित करें और पहली त्रुटि वाले फ़ील्ड पर फ़ोकस सेट करें। इससे उपयोगकर्ता अनुभव बेहतर होता है — उपयोगकर्ता तुरंत देखता है कि किस फ़ील्ड को सही करने की आवश्यकता है।
struct ValidatedForm: View {
enum Field: Hashable { case name; case phone }
@State var name = ""
@State var phone = ""
@FocusState var focusedField: Field?
@State var errors: [String] = []
var body: some View {
Form {
TextField("Name", text: $name)
.focused($focusedField, equals: .name)
TextField("Phone", text: $phone)
.focused($focusedField, equals: .phone)
Button("सबमिट") { validateAndSubmit() }
}
}
func validateAndSubmit() {
if name.isEmpty {
focusedField = .name
return
}
if phone.isEmpty {
focusedField = .phone
return
}
// फ़ॉर्म सबमिट करें
}
}
इस उदाहरण में, यदि name फ़ील्ड खाली है, तो फ़ोकस उस पर चला जाता है, और उपयोगकर्ता तुरंत देखता है कि त्रुटि कहाँ है। यदि name भरा हुआ है, तो phone की जाँच की जाती है। यह फ़ॉर्म के लिए स्वाभाविक व्यवहार है — उपयोगकर्ता ऊपर से नीचे तक फ़ील्ड भरता है, और सत्यापन उसी क्रम का पालन करता है।
सबसे आम गलती Hashable के अनुरूप न होने वाले प्रकार के साथ @FocusState का उपयोग करने का प्रयास करना है। @FocusState के लिए आवश्यक है कि प्रॉपर्टी का प्रकार Hashable हो (Bool और वैकल्पिक enums पहले से ही अनुरूप हैं)। यदि आप कस्टम स्ट्रक्चर का उपयोग करने का प्रयास कर रहे हैं, तो सुनिश्चित करें कि यह Hashable लागू करता है।
// ❌ गलत: enum के बजाय दो @FocusState Bool
@FocusState var isNameFocused: Bool
@FocusState var isEmailFocused: Bool
// ✅ सही: एकल enum @FocusState
enum Field: Hashable { case name; case email }
@FocusState var focusedField: Field?
अक्सर पूछे जाने वाले प्रश्न
@FocusState iOS 15, iPadOS 15, macOS 12, tvOS 15 और watchOS 8 से उपलब्ध है। iOS 14 और उससे नीचे का समर्थन करने वाली परियोजनाओं के लिए, UITextField और becomeFirstResponder के साथ UIViewRepresentable का उपयोग करें, या कस्टम फ़ोकस प्रबंधन कार्यान्वयन के साथ तीसरे पक्ष की लाइब्रेरी का उपयोग करें।
हाँ, इसके लिए कस्टम UIViewRepresentable में UIViewRepresentable प्रोटोकॉल के माध्यम से FocusState समर्थन लागू करना होगा। कस्टम View में becomeFirstResponder और resignFirstResponder होना चाहिए। यदि आप .focused() मॉडिफ़ायर निर्दिष्ट करते हैं तो SwiftUI स्वचालित रूप से @FocusState को इन विधियों से जोड़ देगा।
List या Form में, कोशिकाओं का पुन: उपयोग किया जा सकता है, जो फ़ील्ड के साथ @FocusState बाइंडिंग को तोड़ देता है। समाधान: प्रत्येक TextField के लिए एक अद्वितीय पहचानकर्ता के साथ .id() मॉडिफ़ायर जोड़ें। उदाहरण के लिए: .id(fieldName)। यह SwiftUI को प्रत्येक फ़ील्ड के लिए एक अलग View इंस्टेंस बनाने के लिए मजबूर करता है।
रूट कंटेनर (VStack, ZStack) पर .onTapGesture जोड़ें और फ़ोकस रीसेट करें: focusedField = nil। हालाँकि, .onTapGesture अंदर के बटनों पर टैप को ब्लॉक कर सकता है — .contentShape(Rectangle()) के साथ कंटेनर और उस पर .onTapGesture का उपयोग करें, या कस्टम UIKitBackgroundView का उपयोग करें।
@FocusState कीबोर्ड एनिमेशन के लिए सीधा API प्रदान नहीं करता — यह iOS सिस्टम व्यवहार है। हालाँकि, आप .onChange(of: focusedField) या .onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillShowNotification)) के साथ फ़ोकस परिवर्तनों पर कस्टम सामग्री एनिमेशन के लिए प्रतिक्रिया कर सकते हैं।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें