@FocusState — nədir, SwiftUI-də fokusun və klaviaturanın idarə edilməsi

Müəllif: IT Sectr Dərc olunub: 2026-06-26 Oxuma vaxtı: 9 dəq

@FocusState — SwiftUI-də iOS 15-də təqdim edilmiş, mətn sahələrində və digər elementlərdə daxiletmə fokusunu proqramlı idarə etməyə imkan verən property wrapper-dır. O yaranana qədər, tərtibatçılar UIKit metodlarına — becomeFirstResponder və resignFirstResponder — daxil olmaq üçün UIViewRepresentable istifadə etməli idilər. @FocusState bu problemi doğma şəkildə həll edir: xassəni .focused() modifikatoru vasitəsilə sahə ilə əlaqələndirirsiniz, bundan sonra fokusun qurulması və ya sıfırlanması sadəcə dəyər təyin etməklə baş verir. Apple Developer Documentation — FocusState (2025) məlumatına görə, @FocusState iki rejimi dəstəkləyir: sadə idarəetmə üçün Bool (fokus var və ya yox) və bir neçə sahə üçün enum, burada hər bir case müəyyən daxiletmə sahəsinə uyğun gəlir.

Başlıca

  • @FocusState — SwiftUI-də proqramlı fokus idarəetməsi üçün property wrapper, iOS 15-dən mövcuddur.
  • Bool rejimi — bir sahə üçün @FocusState var isFocused: Bool ilə .focused($isFocused) istifadə edin.
  • Enum rejimi — bir neçə sahə üçün FocusStateValue protokolu ilə enum və .focused($field, equals: .fieldName) istifadə edin.
  • Klaviaturanın gizlədilməsi — klaviaturanı gizlətmək üçün fokusu nil və ya false olaraq təyin edin.
  • Avtomatik fokus — ekran açıldıqda klaviaturanı göstərmək üçün .onAppear-də ilkin dəyəri təyin edin.

SwiftUI-də @FocusState nədir

@FocusState — SwiftUI-də fokus vəziyyətini müəyyən daxiletmə sahəsi və ya digər focusable elementi ilə əlaqələndirən property wrapper-dır. UIKit-dən fərqli olaraq, burada fokusun idarə edilməsi becomeFirstResponder və resignFirstResponder metodları vasitəsilə baş verir, SwiftUI deklarativ yanaşma istifadə edir: vəziyyəti (@FocusState) elan edirsiniz və onu .focused() modifikatoru vasitəsilə elementlə əlaqələndirirsiniz. Vəziyyətin dəyişməsi avtomatik olaraq fokusu dəyişir.

@FocusState iOS 15-də ortaya çıxana qədər, tərtibatçılar UITextField ətrafında UIViewRepresentable qurmalı və ya üçüncü tərəf kitabxanalarından istifadə etməli idilər. @FocusState birbaşa SwiftUI ilə inteqrasiya olunub və TextField, TextEditor, SecureField və SearchField ilə işləyir. Bu, kodu təmizləyir, UIKit körpülərinin sayını azaldır və test edilə bilməni yaxşılaşdırır.

WWDC Session 10136 — What's new in SwiftUI (2024)-yə görə, @FocusState elementlər arasında fokus haqqında məlumat ötürmək üçün SwiftUI preference-açarlar sistemindən istifadə edir. Sahə fokus aldıqda, SwiftUI avtomatik olaraq əlaqəli @FocusState xassəsini yeniləyir ki, bu da kodda fokus dəyişikliklərinə reaksiya verməyə imkan verir.

Bool ilə fokusun idarə edilməsi

@FocusState-dən istifadənin ən sadə yolu — Bool tipi. Sahə fokusda olduqda, xassə true dəyərinə bərabərdir. Fokus getdikdə — false. Siz true təyin etməklə fokusu məcburən qura və ya false təyin etməklə sıfırlaya bilərsiniz.

swift
struct LoginForm: View {
    @State var email = ""
    @FocusState var isEmailFocused: Bool
    
    var body: some View {
        VStack {
            TextField("Email", text: $email)
                .focused($isEmailFocused)
            
            Button("Klaviaturanı göstər") {
                isEmailFocused = true
            }
            Button("Klaviaturanı gizlət") {
                isEmailFocused = false
            }
        }
    }
}

Bu nümunədə isEmailFocused istifadəçi mətn sahəsinə toxunduqda avtomatik olaraq true, klaviatura gizləndikdə isə false olur. Dümələr fokusu proqramlı idarə etməyə imkan verir — bu, xüsusi klaviaturalar, „Növbəti” dümələri və formanın göndərilməsindən sonra klaviaturanı məcburən gizlətmək lazım olduqda faydalıdır.

Bir neçə sahə üçün Enum ilə fokusun idarə edilməsi

Bir neçə sahəli formalar üçün @FocusState FocusStateValue (və ya Hashable) protokoluna uyğun enum dəstəkləyir. Hər bir enum case müəyyən sahəyə uyğun gəlir. Bu, sahələr arasında fokus keçidinə imkan verir — məsələn, klaviaturada „Növbəti” düməsinə basıldıqda növbəti sahəyə keçmək.

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 modifikatoruna diqqət yetirin — o, istifadəçi klaviaturada „Return” düməsinə basdıqda çağırılır. .onSubmit daxilində focusedField-i növbəti sahəyə keçiririk, bu da avtomatik olaraq fokusu köçürür. Son sahə formanı göndərmək üçün submitForm() çağırır.

Klaviaturanın gizlədilməsi və göstərilməsi

@FocusState klaviaturanı gizlətməyin sadə yolunu təmin edir — xassəni nil (enum üçün) və ya false (Bool üçün) olaraq təyin etmək kifayətdir. Bununla belə, bəzən klaviaturanı müəyyən sahəyə bağlı olmadan gizlətmək lazımdır — məsələn, boş yerə toxunduqda. Bu halda bir neçə yanaşma var.

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("Hazır") {
                        isFocused = false
                    }
                }
            }
    }
}

placement .keyboard ilə .toolbar modifikatoru klaviaturanın üzərində dümə əlavə edir. Bu, iOS-da klaviaturanı gizlətmək üçün standart UX nümunəsidir. Alternativ yanaşma — fonə toxunduqda fokusu sıfırlamaq üçün kök VStack-də .onTapGesture istifadə etməkdir.

Fokus və formanın yoxlanması

@FocusState formanın yoxlanması ilə əla boyda birləşir. Tipik nümunə: „Göndər” düməsinə basıldıqdan sonra bütün sahələri yoxlayın və fokusu səhv olan ilk sahəyə qurun. Bu, istifadəçi təcrübəsini yaxşılaşdırır — istifadəçi dərhal hansı sahənin düzəliş tələb etdiyini görür.

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("Göndər") { validateAndSubmit() }
        }
    }
    
    func validateAndSubmit() {
        if name.isEmpty {
            focusedField = .name
            return
        }
        if phone.isEmpty {
            focusedField = .phone
            return
        }
        // formanı göndər
    }
}

Bu nümunədə, name sahəsi boş olduqda, fokus ona köçür və istifadəçi dərhal səhvin harada olduğunu görür. Əgər name doldurulubsa, phone yoxlanılır. Bu, formalar üçün təbii davranışdır — istifadəçi sahələri yuxarıdan aşağı doldurur və yoxlama eyni ardıcıllığa əməl edir.

@FocusState ilə tipik səhvlər

Ən tez-tez rast gəlinən səhv — @FocusState-i Hashable-a uyğun olmayan tip ilə istifadə etməyə cəhd etməkdir. @FocusState xassə tipinin Hashable olmasını tələb edir (Bool və ixtiyari enum artıq uyğundur). Xüsusi struktur istifadə etməyə çalışırsınızsa, onun Hashable-ı tətbiq etdiyinə əmin olun.

  • .focused() modifikatoru unutmusunuz — @FocusState özü fokusu idarə etmir. Onu mütləq .focused($property) və ya .focused($property, equals: .case) vasitəsilə sahə ilə əlaqələndirmək lazımdır.
  • Bir View-də bir neçə @FocusState — bir neçə sahə üçün enum ilə bir @FocusState istifadə edin, bir neçə @FocusState xassəsi yox. Bir neçə Bool xassəsi bir-biri ilə sinxronlaşdırılmayacaq.
  • @FocusState-i main thread-dən kənarda dəyişmək — @FocusState yalnız main thread-də dəyişdirilməlidir, SwiftUI-dəki bütün UI xassələri kimi. Asinxron əməliyyatlar dəyişiklikdən əvvəl MainActor-a keçməlidir.
  • Yenidənqurma zamanı fokusun sıfırlanması — View yenidən qurulursa, @FocusState sıfırlana bilər. View-in sabit identifikasiyası üçün .id() modifikatorundan istifadə edin.
swift
// ❌ Səhv: enum əvəzinə iki @FocusState Bool
@FocusState var isNameFocused: Bool
@FocusState var isEmailFocused: Bool

// ✅ Düzgün: tək enum @FocusState
enum Field: Hashable { case name; case email }
@FocusState var focusedField: Field?

Tez-tez verilən suallar

@FocusState iOS-un hansı versiyalarından mövcuddur?

@FocusState iOS 15, iPadOS 15, macOS 12, tvOS 15 və watchOS 8-dən mövcuddur. iOS 14 və daha köhnə versiyaları dəstəkləyən layihələr üçün UITextField və becomeFirstResponder ilə UIViewRepresentable və ya fokus idarəetməsinin xüsusi tətbiqi ilə üçüncü tərəf kitabxanalarından istifadə edin.

@FocusState-i xüsusi UIViewRepresentable ilə istifadə etmək olarmı?

Bəli, bunun üçün xüsusi UIViewRepresentable-də FocusState dəstəyini UIViewRepresentable protokolu vasitəsilə tətbiq etmək lazımdır. Xüsusi view-də becomeFirstResponder və resignFirstResponder olmalıdır. SwiftUI .focused() modifikatoru göstərilərsə, @FocusState-i avtomatik olaraq bu metodlarla əlaqələndirəcək.

Nü üçün @FocusState List-də TextField ilə işləmir?

List və ya Form hücrələri təkrar istifadə edilə bilər ki, bu da @FocusState-in sahə ilə əlaqəsini pozur. Həll yolu: hər TextField üçün unikal identifikatorla .id() modifikatoru əlavə edin. Məsələn: .id(fieldName). Bu, SwiftUI-ni hər sahə üçün ayrı View nüsxəsi yaratmağa məcbur edir.

Boş yerə toxunduqda klaviaturanı necə gizlətmək olar?

Kök konteynerə (VStack, ZStack) .onTapGesture əlavə edin və fokusu sıfırlayın: focusedField = nil. Bununla belə, .onTapGesture içəridəki dümƏlərə toxunuşları bloklaya bilər — .contentShape(Rectangle()) ilə konteyner və onun üzərində .onTapGesture istifadə edin, ya da xüsusi UIKitBackgroundView istifadə edin.

@FocusState ilə klaviaturanın görünməsini animasiya etmək olarmı?

@FocusState klaviatura animasiyası üçün birbaşa API təmin etmir — bu, iOS-un sistem davranışıdır. Bununla belə, fokus dəyişikliklərinə .onChange(of: focusedField) və ya .onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillShowNotification)) vasitəsilə reaksiya verərək məzmunun xüsusi animasiyasını edə bilərsiniz.

Nəticə

  • @FocusState — daxiletmə fokusunu idarə etmək üçün doğma SwiftUI property wrapper, iOS 15-dən mövcuddur.
  • İki rejim — bir sahə üçün Bool, bir neçə forma sahəsi üçün Hashable enum.
  • .focused() modifikatoru — @FocusState-in müəyyən daxiletmə sahəsi ilə əlaqələndirilməsi üçün məcburidir.
  • Proqramlı idarəetmə — nil və ya false dəyərinin təyini klaviaturanı gizlədir.
  • Forma yoxlanması — @FocusState yoxlamadan sonra fokusu səhv olan ilk sahəyə qurmağa imkan verir.
  • Bir neçə sahə üçün Enum — enum ilə bir @FocusState bir neçə Bool xassəsindən üstündür.
  • iOS 15+ — köhnə versiyalar üçün becomeFirstResponder ilə UIViewRepresentable istifadə edin.

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun