Əsas məqamlar
UIGestureRecognizer — UIKit-də abstrakt əsas sinifdir, jest tanıma prosesini ayrı obyektlərə bölür. Hər alt sinif bir jest növünə cavabdehdir: UITapGestureRecognizer — müəyyən sayda barmaqla tap üçün, UISwipeGestureRecognizer — müəyyən istiqamətdə sürüşdürmə üçün. Tərtibatçı UIView-ə addGestureRecognizer(:) metodu ilə tanıyıcı əlavə edir və UIKit avtomatik olaraq toxunmaları izləyir, vəziyyəti yeniləyir və tanıma zamanı aksiyanı çağırır.
UIGestureRecognizer (iOS 3.2, 2010) meydana çıxmazdan əvvəl tərtibatçılar UIResponder metodlarını — touchesBegan, touchesMoved, touchesEnded — ləğv edir və toxunma trayektoriyasını əl ilə təhlil edirdilər. Bu, kodun təkrarlanmasına və eyni vaxtda toxunmaların işlənməsində səhvlərə səbəb olurdu. Apple bu məntiqi UIGestureRecognizer-də inkapsulyasiya edərək multitouch, jestlərin ləğvi və bir görünüşdə çoxsaylı tanıyıcıların eyni vaxtda işləməsi dəstəyini əlavə etdi.
WWDC sessiyalarına görə, Gesture Recognizer iPad-də 11 eyni vaxtda toxunma və iPhone-da 5 toxunma emal edir. IT Sectr-də UIGestureRecognizer-i bütün UIKit layihələrində istifadəçi girişini idarə etməyin standart yolu kimi istifadə edirik — bu, touchesBegan ilə əl ilə izləmə ilə bağlı səhvləri aradan qaldırdı.
Hər UIGestureRecognizer UIGestureRecognizer.State enumunda müəyyən edilmiş 7 mümkün vəziyyətdən keçir. Bu vəziyyətlər tanıma dövrünü əks etdirir: toxunmanın müəyyən edilməsindən jestin tamamlanmasına və ya ləğvinə qədər. Vəziyyətləri başa düşmək xüsusi tanıyıcıların tətbiqi və münaqişələrin aradan qaldırılması üçün vacibdir.
| Vəziyyət | Mənası | Nə zaman yaranır |
|---|---|---|
| .possible | Başlanğıc vəziyyət, jest hələ tanınmayıb | Görünüşə əlavə edildikdən dərhal sonra |
| .began | Jest tanındı və icra olunmağa başladı | Pan/longPress üçün barmağın ilk hərəkətində |
| .changed | Jestin parametrləri dəyişdi (koordinatlar, bucaq) | Hər barmaq hərəkətində |
| .ended | İstifadəçi barmağını çəkdi, jest tamamlandı | touchesEnded zamanı |
| .cancelled | Jest sistem tərəfindən dayandırıldı (zəng, oriyentasiya dəyişməsi) | touchesCancelled zamanı |
| .failed | Jest şərtlərə görə tanınmadı | Tanınmadan touchesCancelled zamanı |
| .recognized | .ended ilə sinonim; jest uğurla tanındı | .ended ilə eyni |
Diskret jestlər (tap, swipe) .possible-dan birbaşa .ended və ya .failed-a keçir. Davamlı jestlər (pan, pinch, rotation, longPress) .possible → .began → .changed (çoxsaylı) → .ended keçir. Aksiya metodunda gestureRecognizer.state-i yoxlayın — bu, jestin başlanğıcını, dəyişməsini və sonunu fərqləndirməyə imkan verir.
UIKit UIGestureRecognizer-in 7 daxili alt sinfini təqdim edir, əksər qarşılıqlı təsir ssenarilərini əhatə edir. Hər alt sinfin spesifik parametrləri var: numberOfTapsRequired tap üçün, direction sürüşdürmə üçün, minimumPressDuration uzun basma üçün.
Xüsusi jestlər üçün (məsələn, ziqzaq çəkmək) UIGestureRecognizer alt sinfi touchesBegan, touchesMoved, touchesEnded metodlarını ləğv etməklə və state-i yeniləməklə yaradılır. Apple mümkün olduqda daxili siniflərdən istifadə etməyi tövsiyə edir — onlar optimallaşdırılmışdır və bir-biri ilə düzgün qarşılıqlı əlaqədə olur.
Bir UIView-də bir neçə UIGestureRecognizer istifadə edildikdə (məsələn, tap və double-tap), tanıma münaqişəsi yaranır: cüt tap zamanı əvvəlcə tək tap işə düşür. Həll üçün Apple require(toFail:) metodunu təqdim edir, bu, bir jestin tanınmasını digəri uğursuzluqla bitənə qədər gecikdirir.
Mexanizm belə işləyir: tapRecognizer.require(toFail: doubleTapRecognizer) çağırmaqla tapRecogniser-in .recognized vəziyyətinə yalnız doubleTapRecogniser .failed ilə bitdikdən sonra keçəcəyini göstərirsiniz. Bu, tək tapın icrasından əvvəl ~0.3 saniyə gecikmə əlavə edir — istifadəçi iki dəfə basır, birinci tap nəzərə alınmır. Alternativ metod — gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:) metodu ilə UIGestureRecognizerDelegate, eyni vaxtda tanımaya icazə verir (məsələn, xəritə üçün pan + pinch).
WWDC 2020 məlumatına görə, UIKit tətbiqlərində səhvlərin təxminən 15%-i jest münaqişələrinin səhv konfiqurasiyası ilə bağlıdır. IT Sectr-də yanaşmanı standartlaşdırdıq: hər ekran üçün require(toFail:) prioritetləri göstərilmiş jest sxemi yaradılır — bu, tapların ikiqat işə düşməsi ilə bağlı səhvləri tamamilə aradan qaldırdı.
UIImageView-də tək tap işləyicisi əlavə edir. Tap zamanı şəkil şəffaflığı dəyişir — jestin görünüşə bağlanmasını göstərən ən sadə nümunə.
import UIKit
class ImageViewController: UIViewController {
@IBOutlet private var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(
target: self,
action: #selector(handleTap(_:))
)
tap.numberOfTapsRequired = 1
imageView.addGestureRecognizer(tap)
imageView.isUserInteractionEnabled = true
}
@objc private func handleTap(_: UITapGestureRecognizer) {
UIView.animate(withDuration: 0.2) {
self.imageView.alpha = self.imageView.alpha == 1.0 ? 0.5 : 1.0
}
}
}
Əsas məqam: UIImageView-də isUserInteractionEnabled standart olaraq false-dir — bu bayraq olmadan Gesture Recognizer toxunmaları qəbul etməyəcək. UIView və UIButton üçün bayraq standart olaraq aktivdir. Aksiya metodu UITapGestureRecognizer parametrini qəbul edir, onun vasitəsilə tapın koordinatlarını təyin etmək üçün location(in:) əldə etmək olar.
Əvvəlki ekrana qayıtmaq üçün sola sürüşdürməni həyata keçirir. İstiqamətin konfiqurasiyasını və jestin kök görünüşünə bağlanmasını nümayiş etdirir.
import UIKit
class DetailViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let swipeLeft = UISwipeGestureRecognizer(
target: self,
action: #selector(handleSwipe(_:))
)
swipeLeft.direction = .left
view.addGestureRecognizer(swipeLeft)
}
@objc private func handleSwipe(_: UISwipeGestureRecognizer) {
navigationController?.popViewController(animated: true)
}
}
UISwipeGestureRecognizer — diskret jestdir: tanındıqdan dərhal sonra .recognised vəziyyətinə keçir, aralıq .changed olmadan. Buna görə aksiyada state-i yoxlamaq lazım deyil — jest ya tanınır (aksija çağırılır), ya da yox. direction xassəsi dörd dəyərdən birini qəbul edir: .left, .right, .up, .down. Çoxlu istiqamətləri dəstəkləmək üçün hər biri üçün ayrı tanıyıcı yaradın.
Bir görünüşdə münaqişəsiz tək və cüt tapın necə konfiqurasiya olunacağını göstərir. Cüt tap tanıyıcısı prioritetə malikdir — tək tap yalnız cüt tap tanınmadıqda işə düşür.
import UIKit
class TapViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let singleTap = UITapGestureRecognizer(
target: self,
action: #selector(handleSingleTap)
)
singleTap.numberOfTapsRequired = 1
let doubleTap = UITapGestureRecognizer(
target: self,
action: #selector(handleDoubleTap)
)
doubleTap.numberOfTapsRequired = 2
singleTap.require(toFail: doubleTap)
view.addGestureRecognizer(singleTap)
view.addGestureRecognizer(doubleTap)
}
@objc private func handleSingleTap() {
print("Single tap — after 0.3s delay")
}
@objc private func handleDoubleTap() {
print("Double tap — instant")
}
}
require(toFail:) olmadan cüt tap zamanı əvvəlcə handleSingleTap, sonra handleDoubleTap çağırılır — bu UX-i pozur. require(toFail:) ilə tək tap ~0.3 saniyə gözləyir ki, ikinci tapın gəlməyəcəyinə əmin olsun. IT Sectr-də bu nümunə şəkil redaktorlarında və qalereyalarda istifadə olunur, burada cüt tap yaxınlaşdırır, tək tap isə elementi seçir.
Tez-tez verilən suallar
Bəli, UIView eyni vaxtda çoxsaylı UIGestureRecognizer dəstəkləyir. Münaqişələri həll etmək üçün tanıma sırasını təyin edən require(toFail:) metodundan istifadə edin. Jestlərin paralel işləməsi üçün (məsələn, xəritədə pan + pinch) true qaytaran gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:) delegatını tətbiq edin.
UIGestureRecognizer — toxunma nümunələrini avtomatik tanıyan və vəziyyətləri idarə edən yüksək səviyyəli abstraksiyadır. touchesBegan — koordinatların, vaxtın və toxunmaların ləğvinin əl ilə izlənilməsini tələb edən UIResponder-in aşağı səviyyəli metodudur. Gesture Recognizer daha sadə, daha etibarlı və standart jestlər üçün üstünlük təşkil edir; touchesBegan yalnız xüsusi qrafika üçün əsaslandırılmışdır.
Yerli SwiftUI-də modifikatorlardan istifadə olunur: onTapGesture, onLongPressGesture, DragGesture, MagnificationGesture, RotationGesture. Bunlar SwiftUI iyerarxiyasına inteqrasiya olunmuş UIGestureRecognizer-in deklarativ analoqlarıdır. Lazım gələrsə, UIKit tanıyıcısını UIViewRepresentable vasitəsilə bükə bilərsiniz, lakin Apple yerli SwiftUI jestlərindən istifadə etməyi tövsiyə edir.
Nəticə
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.
Həm də oxuyun