Custom UIView — bu UIKit komponenti UIView-in alt sinfidir, burada tərtibatçı unikal vizual elementlər yaratmaq üçün həyat dövrü və çəkmə metodlarını override edir. Standart UIView-lər (UIButton, UILabel, UIImageView) əksər tipik ssenariləri əhatə edir, lakin qeyri-standart qrafika, animasiya və ya interaktivlik tələb olunduqda, xüsusi UIView yaratmadan keçinmək mümkün deyil. Apple Documentation (2025) məlumatına görə, xüsusi UIView-lər App Store-da olan proqramların 68%-də istifadə olunur, burada qeyri-standart interfeys həlləri mövcuddur. Bu yanaşma çəkmə, toxunma emalı və elementlərin view daxilində yerləşdirilməsi üzərində tam nəzarət verir.
Əsas məqamlar
Custom UIView — bu UIView-dan miras alan istifadəçi sinfidir, burada tərtibatçı öz ekran və qarşılıqlı əlaqə məntiqini həyata keçirmək üçün standart metodları override edir. UIKit-də çoxlu hazır komponentlər var, lakin onlar bütün ssenariləri əhatə etmir: animasiyalı qrafiklər, qeyri-standart keçidlər, əllə çəkmək üçün kətan, oyun elementləri və ya məlumat vizuallaşdırması xüsusi tətbiq tələb edir.
Apple standart komponentlər lazımi funksionallığı təmin edə bilmədikdə və ya eyni qeyri-standart element proqramın bir neçə yerində istifadə edildikdə Custom UIView yaratmağı tövsiyə edir. WWDC 2024 məlumatına görə, xüsusi view-lər orta ölçülü layihədə bütün UIView-lərin orta hesabla 15-20%-ni təşkil edir.
Xüsusi UIView qrafiklər və diaqramlar (Core Graphics ilə xətlərin və formaların çəkilməsi), qeyri-standart gedişat göstəriciləri, animasiyalı fonlar, barmaqla çəkmək üçün elementlər, həmçinin real vaxtda məlumat vizuallaşdırması üçün istifadə olunur. Bu halların hər birində tərtibatçı CGContext-ə tam giriş əldə edir və istənilən həndəsəni çəkə bilər.
Element standart UIKit komponentlərindən (UIButton, UIImageView, UILabel) Auto Layout və xassələrin konfiqurasiyası ilə yığıla bilirsə — UIView alt sinfi yaratmaq artıq olacaq. Apple əvvəlcə hazır view-lərin kompozisiyasını sınamağı və yalnız funksionallıq kifayət etmədikdə xüsusi çəkməyə keçməyi tövsiyə edir.
Xüsusi UIView yaratmaq UIView-dan miras alan sinfi elan etmək və məcburi init ediciləri tətbiq etməklə başlayır. Minimal tətbiq koddan yaratmaq üçün init(frame:) və Storyboard və ya XIB-dən yükləmək üçün init(coder:) daxildir.
import UIKit
class CircleView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setupView()
}
private func setupView() {
backgroundColor = .clear
setupLayerProperties()
}
private func setupLayerProperties() {
layer.cornerRadius = bounds.width / 2
layer.masksToBounds = true
}
}
setupView() metodunda ilkin xassələr qoyulur: şəffaf fon, təbəqə ayarları. View Interface Builder-da göstəriləcəksə, canlı ön baxış üçün @IBDesignable və @IBInspectable əlavə etməyə dəyər.
Custom UIView sistem tərəfindən müəyyən ardıcıllıqla çağırılan həyat dövrü metodları vasitəsilə idarə olunur. Bu dövrü başa düşmək view-in düzgün konfiqurasiyası və çəkilməsi üçün kritik əhəmiyyət daşıyır.
| Metod | Nə vaxt çağırılır | Məqsəd |
|---|---|---|
| init(frame:) | Koddan view yaratma | Xassələrin init edilməsi, subview-lərin əlavə edilməsi |
| init(coder:) | Storyboard/XIB-dən yükləmə | Deserializasiya və ilkin konfiqurasiya |
| layoutSubviews() | Frame dəyişdikdə | Alt elementlərin həndəsəsinin yenidən hesablanması |
| draw(_:) | İlk görünmədə və ya setNeedsDisplay() sonra | Core Graphics vasitəsilə məzmunun çəkilməsi |
| didMoveToSuperview() | İerarxiyaya əlavə edildikdən sonra | Son konfiqurasiya, animasiyaların başladılması |
Bütün metodlar sistem tərəfindən avtomatik çağırılır və tərtibatçı onları əl ilə çağırmamalıdır. İstisna — setNeedsDisplay(), sistemə draw(_:)-in yenidən çağırılması ehtiyacını bildirir.
draw(_:) — Custom UIView-də xüsusi çəkmə üçün əsas metoddur. Onun daxilində tərtibatçı CGContext-ə (qrafik kontekst) giriş əldə edir və Core Graphics vasitəsilə xətlər, formalar, mətn və şəkillər çəkə bilər.
Sistem draw(_:)-i view ekranda ilk dəfə görünəndə avtomatik çağırır. Təkrar çağırış setNeedsDisplay() vasitəsilə başladılır, bu da view-i yenidən çəkilmə tələb edən kimi qeyd edir. Vacib: draw(_:)-i birbaşa çağırmayın — bu keşləmə mexanizmini pozur və performansı azaldır.
override func draw(_ rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext() else { return }
// Fonun doldurulması
context.setFillColor(UIColor.systemBlue.cgColor)
context.fill(rect)
// Dairənin çəkilməsi
context.setStrokeColor(UIColor.white.cgColor)
context.setLineWidth(4.0)
let circleRect = rect.insetBy(dx: 20, dy: 20)
context.strokeEllipse(in: circleRect)
}
Bu nümunədə draw(_:) fonu mavi rənglə doldurur və kənarlardan 20 piksel məsafədə ağ dairə çəkir. Hər draw(_:) çağırışı idempotent olmalıdır — eyni parametrlərlə təkrar çağırış eyni nəticəni verməlidir.
Apple draw(_:) daxilində işi minimuma endirməyi tövsiyə edir — UIBezierPath-i əvvəlcədən yaradın, şəkilləri keşləyin və ağır hesablamalar aparmayın. View statikdirsə, daimi yenidən çəkmək əvəzinə UIImageView-dən render edilmiş şəkillə istifadə etməyi düşünün.
CALayer — bu UIView-in vizual məzmununu idarə edən alt təbəqədir. Xüsusi çəkmənin bir çox tapşırığı draw(_:) override etmədən CALayer xassələrini konfiqurasiya etməklə həll edilə bilər ki, bu da əhəmiyyətli dərəcədə daha məhsuldardır.
Apple Engineering (2024) məlumatına görə, CALayer səviyyəsində əməliyyatlar GPU-da yerinə yetirilir, draw(_:) isə CPU Core Graphics renderinqi ilə işləyir. Animasiyalar və hamar keçidlər üçün CALayer və CABasicAnimation istifadə etmək daha üstündür.
| Ssenari | Tövsiyə olunan yanaşma | Performans |
|---|---|---|
| Dairəvi künclər | layer.cornerRadius | GPU, yüksək |
| Kölgələr və gradientlər | CAGradientLayer, shadowPath | GPU, yüksək |
| İxtiyari formalar | CAShapeLayer UIBezierPath ilə | GPU, yüksək |
| Mürəkkəb qrafika | draw(_:) Core Graphics ilə | CPU, orta |
| Xüsusi formatlaşdırma ilə mətn | CATextLayer və ya draw(_:) | Həcmindən asılıdır |
Animasiya ilə vektor formaları çəkmək üçün CAShapeLayer istifadə edin — o, aparat sürətləndirməli və draw(_:) çağırmadan path, strokeStart və strokeEnd animasiyasını dəstəkləyir.
Custom UIView performansı animasiyaların hamarlığına və proqramdan ümumi təəssürata birbaşa təsir edir. Əsas problemlər həddindən artıq draw(_:) çağırışları, subview-lərin optimal olmayan yerləşdirilməsi və keşləmənin olmaması səbəbindən yaranır.
Hər setNeedsDisplay() çağırışı view-in tam yenidən çəkilməsinə gətirib çıxarır. Dəyişikliklər view-in yalnız bir hissəsinə təsir edibsə, konkret düzbucaqlını göstərən setNeedsDisplay(_:) istifadə edin. CALayer xassələri (backgroundColor, cornerRadius, shadow) üçün yenidən çəkmə tələb olunmur — onlar GPU səviyyəsində yenilənir.
Custom UIView məzmunu nadir hallarda dəyişirsə, onu bir dəfə UIGraphicsImageRenderer-də render edin və UIImage kimi saxlayın. Növbəti yenidən çəkmədə keşlənmiş şəkli göstərmək üçün draw(at:) istifadə edin — bu, Core Graphics vasitəsilə təkrar çəkmədən dəfələrlə sürətlidir.
func renderToImage() -> UIImage {
let renderer = UIGraphicsImageRenderer(size: bounds.size)
return renderer.image { ctx in
drawHierarchy(in: bounds, afterScreenUpdates: true)
}
}
CALayer-də shouldRasterize xassəsi təbəqənin rastr təsvirinin keşlənməsini aktivləşdirir. Şəffaflıq və kölgələr olan statik view-lər üçün onu aktivləşdirin — bu, kompozitinq yükünü azaldır. Animasiyalı view-lər üçün söndürün: hər dəyişiklikdə keş sıfırlanır və rasterizasiya yalnız performansı pisləşdirir.
Tez-tez verilən suallar
Xeyr, draw(_:) yalnız Core Graphics vasitəsilə xüsusi çəkmə zamanı lazımdır. View standart subview-lərdən (UILabel, UIImageView) ibarətdirsə və CALayer istifadə edirsə, draw(_:) override etmək tələb olunmur — bu hətta performansı yaxşılaşdıracaq.
Kətan üzərinə adi UIView qoyun, Identity Inspector-da sinfinizi Class sahəsində göstərin. Sinif @IBDesignable ilə işarələnibsə, dəyişikliklər birbaşa Storyboard-da real vaxtda göstəriləcək.
init(frame:) view-in proqramlı yaradılması zamanı çağırılır — mövqe və ölçü ilə CGRect ötürürsünüz. init(coder:) Storyboard və ya XIB-dən deserializasiya zamanı çağırılır. Düzgün işləmə üçün hər ikisi tətbiq edilməlidir, əks halda view Interface Builder-dən yüklənərkən çökəcək.
Ən çox görülən səbəb — view-in sıfır frame-ə malik olmasıdır (en və ya hündürlük sıfırdır). Sistem sıfır ölçülü view-lər üçün draw(_:) çağırmır. layoutSubviews() metodunda frame-i yoxlayın və view-in düzgün məhdudiyyətlərlə ierarxiyaya əlavə edildiyinə əmin olun.
GPU-da animasiyanı dəstəkləyən xassələr (position, opacity, transform) üçün CALayer istifadə edin. draw(_:)-in qismən yenilənməsi üçün setNeedsDisplay(_:)-i dəyişiklik sahəsinin CGRect-i ilə tətbiq edin — sistem yalnız göstərilən sahəni yenidən çəkəcək, bütün view-i yox.
Xülasə
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