@FocusState — bu nima, SwiftUI da fokus va klaviaturani boshqarish

Muallif: IT Sectr Nashr etilgan: 2026-06-26 O'qish vaqti: 9 daq

@FocusState — bu SwiftUI da iOS 15 da taqdim etilgan, matn maydonlari va boshqa elementlarda kiritish fokusini dasturiy boshqarish imkonini beruvchi property wrapper. U paydo bo‘lishidan oldin, dasturchilar UIKit metodlari becomeFirstResponder va resignFirstResponderga kirish uchun UIViewRepresentable dan foydalanishlari kerak edi. @FocusState bu muammoni mahalliy usulda hal qiladi: xususiyatni .focused() modifikatori orqali maydon bilan bog‘laysiz, shundan so‘ng fokusni o‘rnatish yoki bekor qilish oddiy qiymat belgilash orqali amalga oshiriladi. Apple Developer Documentation — FocusState (2025) ma’lumotlariga ko‘ra, @FocusState ikkita rejimni qo‘llab-quvvatlaydi: Bool oddiy boshqarish uchun (fokus bor yoki yo‘q) va enum bir nechta maydonlar uchun, har bir case ma’lum bir kiritish maydoniga mos keladi.

Asosiy

  • @FocusState — SwiftUI da dasturiy fokus boshqaruvi uchun property wrapper, iOS 15 dan mavjud.
  • Bool rejimi — bitta maydon uchun @FocusState var isFocused: Bool bilan .focused($isFocused) dan foydalaning.
  • Enum rejimi — bir nechta maydonlar uchun FocusStateValue protokoli bilan enum va .focused($field, equals: .fieldName) dan foydalaning.
  • Klaviaturani yashirish — klaviaturani yashirish uchun fokusni nil yoki false ga o‘rnating.
  • Avtomatik fokus — ekran ochilganda klaviaturani ko‘rsatish uchun .onAppear da boshlang‘ich qiymatni o‘rnating.

SwiftUI da @FocusState nima

@FocusState — bu SwiftUI da fokus holatini ma’lum bir kiritish maydoni yoki boshqa focusable element bilan bog‘laydigan property wrapper. UIKit dan farqli o‘laroq, bu erda fokusni boshqarish becomeFirstResponder va resignFirstResponder metodlari orqali amalga oshiriladi, SwiftUI deklarativ yondashuvdan foydalanadi: holatni (@FocusState) e’lon qilasiz va uni .focused() modifikatori orqali element bilan bog‘laysiz. Holatning o‘zgarishi avtomatik ravishda fokusni o‘zgartiradi.

@FocusState iOS 15 da paydo bo‘lishidan oldin, dasturchilar UITextField atrofida UIViewRepresentable o‘ramlarini yaratishlari yoki uchinchi tomon kutubxonalaridan foydalanishlari kerak edi. @FocusState to‘g‘ridan-to‘g‘ri SwiftUI bilan integratsiyalangan va TextField, TextEditor, SecureField va SearchField bilan ishlaydi. Bu kodni tozaroq qiladi, UIKit ko‘priklari sonini kamaytiradi va test qilish qobiliyatini yaxshilaydi.

WWDC Session 10136 — What's new in SwiftUI (2024) ma’lumotlariga ko‘ra, @FocusState elementlar o‘rtasida fokus haqida ma’lumot uzatish uchun SwiftUI preference kalitlari tizimidan foydalanadi. Maydon fokusni qabul qilganda, SwiftUI avtomatik ravishda bog‘langan @FocusState xususiyatini yangilaydi, bu kodda fokus o‘zgarishlariga reaksiya berish imkonini beradi.

Bool bilan fokusni boshqarish

@FocusState dan foydalanishning eng oddiy usuli — Bool turi. Maydon fokusda bo‘lganda, xususiyat true ga teng. Fokus ketganda — false. Siz true belgilash orqali fokusni majburan o‘rnatishingiz yoki false belgilash orqali bekor qilishingiz mumkin.

swift
struct LoginForm: View {
    @State var email = ""
    @FocusState var isEmailFocused: Bool
    
    var body: some View {
        VStack {
            TextField("Email", text: $email)
                .focused($isEmailFocused)
            
            Button("Klaviaturani koʸrsatish") {
                isEmailFocused = true
            }
            Button("Klaviaturani yashirish") {
                isEmailFocused = false
            }
        }
    }
}

Ushbu misolda, isEmailFocused foydalanuvchi matn maydoniga bosganda avtomatik ravishda true ga aylanadi va klaviatura yashirilganda false bo‘ladi. Tugmalar fokusni dasturiy boshqarish imkonini beradi — bu maxsus klaviaturalar, „Keyingi” tugmalari va formani yuborishdan so‘ng klaviaturani majburan yashirish kerak bo‘lgan vaziyatlarda foydalidir.

Bir nechta maydonlar uchun Enum bilan fokusni boshqarish

Bir nechta maydonli formalar uchun @FocusState FocusStateValue (yoki Hashable) protokoli bilan mos keladigan enum ni qo‘llab-quvvatlaydi. Har bir enum case ma’lum bir maydonga mos keladi. Bu maydonlar o‘rtasida fokusni almashtirish imkonini beradi — masalan, klaviaturada „Keyingi” tugmasini bosganda keyingi maydonga o‘tish.

swift
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 modifikatoriga e’tibor bering — u foydalanuvchi klaviaturada „Return” tugmasini bosganda chaqiriladi. .onSubmit ichida focusedField ni keyingi maydonga o‘tkazamiz, bu avtomatik ravishda fokusni ko‘chiradi. Oxirgi maydon formani yuborish uchun submitForm() ni chaqiradi.

Klaviaturani yashirish va ko‘rsatish

@FocusState klaviaturani yashirishning oddiy usulini taqdim etadi — xususiyatni nil (enum uchun) yoki false (Bool uchun) ga o‘rnatish kifoya. Biroq, ba’zan klaviaturani ma’lum bir maydonga bog‘lamasdan yashirish kerak bo‘ladi — masalan, bo‘sh joyga bosganda. Bu holda bir nechta yondashuvlar mavjud.

swift
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("Tayyor") {
                        isFocused = false
                    }
                }
            }
    }
}

placement .keyboard bilan .toolbar modifikatori klaviatura ustiga tugma qo‘shadi. Bu iOS da klaviaturani yashirish uchun standart UX namunasi. Muqobil yondashuv — fonni bosganda fokusni bekor qilish uchun asosiy VStack da .onTapGesture dan foydalanish.

Fokus va formani tekshirish

@FocusState formani tekshirish bilan ajoyib tarzda birlashadi. Odatiy namuna: „Yuborish” tugmasini bosgandan so‘ng, barcha maydonlarni tekshiring va fokusni xatolik bor birinchi maydonga o‘rnating. Bu foydalanuvchi tajribasini yaxshilaydi — foydalanuvchi darhol qaysi maydonni tuzatish kerakligini ko‘radi.

swift
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("Yuborish") { validateAndSubmit() }
        }
    }
    
    func validateAndSubmit() {
        if name.isEmpty {
            focusedField = .name
            return
        }
        if phone.isEmpty {
            focusedField = .phone
            return
        }
        // formani yuborish
    }
}

Ushbu misolda, name maydoni bo‘sh bo‘lganda, fokus unga o‘tadi va foydalanuvchi darhol xato qayerda ekanligini ko‘radi. Agar name to‘ldirilgan bo‘lsa, phone tekshiriladi. Bu formalar uchun tabiiy xatti-harakat — foydalanuvchi maydonlarni yuqoridan pastga to‘ldiradi va tekshirish ham xuddi shu tartibda amalga oshadi.

@FocusState bilan odatiy xatolar

Eng keng tarqalgan xato — @FocusState ni Hashable ga mos kelmaydigan tur bilan ishlatishga urinish. @FocusState xususiyat turining Hashable bo‘lishini talab qiladi (Bool va ixtiyoriy enum lar allaqachon mos keladi). Agar maxsus strukturadan foydalanishga harakat qilsangiz, uning Hashable ni amalga oshirganiga ishonch hosil qiling.

  • .focused() modifikatorini unutdingiz — @FocusState o‘zi fokusni boshqarmaydi. Uni .focused($property) yoki .focused($property, equals: .case) orqali maydon bilan bog‘lash majburiydir.
  • Bitta View da bir nechta @FocusState — bir nechta maydonlar uchun bir nechta @FocusState xususiyatlari o‘rniga enum bilan bitta @FocusState dan foydalaning. Bir nechta Bool xususiyatlari bir-biri bilan sinxronlashtirilmaydi.
  • @FocusState ni main thread dan tashqarida o‘zgartirish — @FocusState faqat asosiy oqimda o‘zgartirilishi kerak, SwiftUI dagi barcha UI xususiyatlari kabi. Asinxron operatsiyalar o‘zgartirishdan oldin MainActor ga o‘tishi kerak.
  • Qayta qurishda fokusni bekor qilish — agar View qayta qurilsa, @FocusState bekor qilinishi mumkin. View ni barqaror identifikatsiyalash uchun .id() modifikatoridan foydalaning.
swift
// ❌ Xato: enum oʻrniga ikkita @FocusState Bool
@FocusState var isNameFocused: Bool
@FocusState var isEmailFocused: Bool

// ✅ Toʻgʻri: bitta enum @FocusState
enum Field: Hashable { case name; case email }
@FocusState var focusedField: Field?

Tez-tez beriladigan savollar

@FocusState iOS ning qaysi versiyalaridan mavjud?

@FocusState iOS 15, iPadOS 15, macOS 12, tvOS 15 va watchOS 8 dan mavjud. iOS 14 va undan past versiyalarni qo‘llab-quvvatlovchi loyihalar uchun UITextField va becomeFirstResponder bilan UIViewRepresentable yoki fokusni boshqarishning maxsus amalga oshirilishi bilan uchinchi tomon kutubxonalaridan foydalaning.

@FocusState ni maxsus UIViewRepresentable bilan ishlatish mumkinmi?

Ha, buning uchun maxsus UIViewRepresentable da FocusState ni qo‘llab-quvvatlashni UIViewRepresentable protokoli orqali amalga oshirish kerak. Maxsus view da becomeFirstResponder va resignFirstResponder bo‘lishi kerak. SwiftUI .focused() modifikatori ko‘rsatilgan bo‘lsa, @FocusState ni avtomatik ravishda ushbu metodlar bilan bog‘laydi.

Nega @FocusState List dagi TextField bilan ishlamaydi?

List yoki Form da hujayralar qayta ishlatilishi mumkin, bu @FocusState ning maydon bilan bog‘lanishini buzadi. Yechim: har bir TextField uchun noyob identifikator bilan .id() modifikatorini qo‘shing. Masalan: .id(fieldName). Bu SwiftUI ni har bir maydon uchun alohida View nusxasini yaratishga majbur qiladi.

Bo‘sh joyga bosganda klaviaturani qanday yashirish mumkin?

Asosiy konteynerga (VStack, ZStack) .onTapGesture qo‘shing va fokusni bekor qiling: focusedField = nil. Biroq, .onTapGesture ichidagi tugmalarga bosishni bloklashi mumkin — .contentShape(Rectangle()) bilan konteyner va unda .onTapGesture dan foydalaning yoki maxsus UIKitBackgroundView dan foydalaning.

@FocusState bilan klaviatura paydo bo‘lishini animatsiya qilish mumkinmi?

@FocusState klaviatura animatsiyasi uchun to‘g‘ridan-to‘g‘ri API ni taqdim etmaydi — bu iOS ning tizim xatti-harakatidir. Biroq, siz .onChange(of: focusedField) yoki .onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillShowNotification)) yordamida fokus o‘zgarishlariga reaksiya berishingiz va tarkibning maxsus animatsiyasini amalga oshirishingiz mumkin.

Xulosa

  • @FocusState — kiritish fokusini boshqarish uchun mahalliy SwiftUI property wrapper, iOS 15 dan mavjud.
  • Ikki rejim — bitta maydon uchun Bool, bir nechta forma maydonlari uchun Hashable enum.
  • .focused() modifikatori — @FocusState ni ma’lum bir kiritish maydoni bilan bog‘lash uchun majburiydir.
  • Dasturiy boshqaruv — nil yoki false qiymatini o‘rnatish klaviaturani yashiradi.
  • Formani tekshirish — @FocusState tekshirishdan so‘ng fokusni xatolik bor birinchi maydonga o‘rnatish imkonini beradi.
  • Bir nechta maydonlar uchun Enum — enum bilan bitta @FocusState bir nechta Bool xususiyatlaridan afzal.
  • iOS 15+ — eski versiyalar uchun becomeFirstResponder bilan UIViewRepresentable dan foydalaning.

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing