draw(_:) / drawRect — bu UIView sinifinin (Swift-də) və onun Objective-C-dəki (drawRect:) analoqu olan, Core Graphics istifadə edərək görünüş məzmununun çəkilməsinə cavabdeh olan metoddur. Sistem bu metodu görünüş ekranda ilk dəfə görünəndə və setNeedsDisplay() çağırıldıqdan sonra avtomatik çağırır. Apple Documentation (2025) məlumatına görə, draw(_:) proqramçının xüsusi çəkmə üçün cari ekranın qrafik kontekstinə çıxışı olan yeganə metoddur. draw(_:)-i yenidən təyin etmək komponentin görünüşü üzərində tam nəzarət verir — sadə həndəsi fiqurlardan mürəkkəb animasiyalı qrafikə qədər.
Əsas məqamlar
draw(_:) — UIKit-in görünüş məzmununu render etmək üçün çağırdığı UIView nümunə metodudur. Bu metodun daxilində proqramçı CGContext qrafik kontekstinə çıxış əldə edir və xətlər, doldurmalar, mətn və şəkillər çəkmək üçün Core Graphics API-dən istifadə edir. Objective-C-də drawRect: eyni funksiyanı yerinə yetirir, lakin fərqli sintaksislə: yeganə parametr yenidən çəkiləcək sahəni təyin edən CGRect-dir.
Apple Engineering (2024) məlumatına görə, draw(_:) CPU renderinqi Bitmap Graphics Context vasitəsilə işləyir ki, bu da maksimum elastikliyi təmin edir, lakin CALayer ilə müqayisədə daha çox resurs tələb edir. draw(_:) istifadəsi barədə qərar qrafikin mürəkkəbliyinə və performans tələblərinə əsasən qəbul edilir.
Swift-də metod override func draw(_ rect: CGRect) kimi elan edilir, burada rect yenidən çəkilməsi tələb olunan düzbucaqlıdır. Objective-C-də imza - (void)drawRect:(CGRect)rect-dir. rect parametri setNeedsDisplay(_:) vasitəsilə qismən yenidən çəkmə zamanı görünüşün bounds-dən kiçik ola bilər.
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
CGContextFillRect(context, rect);
}
Sistem draw(_:)-i ciddi müəyyən edilmiş ssenarilərdə avtomatik çağırır. Bu tetikleyicileri anlamaq lazımsız yenidən çəkmələrdən qaçmağa və görünüş performansını optimallaşdırmağa kömək edir. Aşağıda metodun avtomatik çağırılmasının bütün halları verilmişdir.
Apple sənədləri xəbərdarlıq edir: heç vaxt draw(_:)-i birbaşa çağırmayın. Sistem özü çəkmənin nə vaxt yerinə yetiriləcəyinə qərar verir və birbaşa çağırış daxili keşləmə mexanizmini pozur. Yenidən çəkmə tələb etmək üçün həmişə setNeedsDisplay() və ya setNeedsDisplay(_:) istifadə edin.
Swift-də draw(_:)-i yenidən təyin etmək qrafik kontekstin əldə edilməsi və ardınca Core Graphics çağırışları ilə başlayır. Çəkmənin məntiqi blokları üçün ayrıca metodlar yaratmaq tövsiyə olunur — bu kodun oxunaqlılığını və test edilə bilməsini yaxşılaşdırır.
override func draw(_ rect: CGRect) {
super.draw(rect)
guard let context = UIGraphicsGetCurrentContext() else { return }
// Xətt parametrləri
context.setStrokeColor(UIColor.darkGray.cgColor)
context.setLineWidth(2.0)
// Üçbucaq çəkmək
context.move(to: CGPoint(x: rect.midX, y: rect.minY + 10))
context.addLine(to: CGPoint(x: rect.maxX - 10, y: rect.maxY - 10))
context.addLine(to: CGPoint(x: rect.minX + 10, y: rect.maxY - 10))
context.closePath()
context.strokePath()
}
Bu nümunədə draw(_:) 2 piksel qalınlığında tünd boz kontur ilə üçbucaq çəkir. Metodun əvvəlində super.draw(rect) çağırışı Apple tərəfindən valideyn çəkmə məntiqini qorumaq üçün tövsiyə olunur, baxmayaraq ki, UIView-də draw(_:)-in standart implementasiyası boşdur.
draw(_:)-in hər çağırışı eyni giriş məlumatları ilə eyni nəticə verməlidir. Bu, sistemə nəticəni keşləməyə və görünüş məzmunu dəyişməyibsə, draw(_:)-i təkrar çağırmamağa imkan verir. draw(_:) daxilində təsadüfi dəyərlər, sistem vaxtı və ya şəbəkə sorğuları istifadə etməyin.
drawRect: — tarixən iOS 2.0 ilə Objective-C ilə birlikdə ortaya çıxan metodun ilk variantıdır. Swift-də metod xarici parametr _ istifadə edərək draw(_:) adlandırıldı. Funksional olaraq metodlar eynidir: hər ikisi yenidən çəkmə sahəsinin CGRect-ni alır və qrafik kontekstə çıxış üçün UIGraphicsGetCurrentContext() istifadə edir.
| Xüsusiyyət | draw(_:) (Swift) | drawRect: (Objective-C) |
|---|---|---|
| İmza | override func draw(_ rect: CGRect) | - (void)drawRect:(CGRect)rect |
| Super çağırışı | super.draw(rect) | [super drawRect:rect] |
| Kontekst | UIGraphicsGetCurrentContext() | UIGraphicsGetCurrentContext() |
| Parametr rect | rect: CGRect | CGRect rect |
| Performans | Eyni | Eyni |
Layihəni Objective-C-dən Swift-ə miqrasiya edərkən metodun adlandırılması ilk vəzifələrdən biridir. Xcode avtomatik çevirici təqdim edir, lakin drawRect: draw(_:)-ə əl ilə yenilənmə tələb edir. Apple (2024) məlumatına görə, Swift versiyası draw(_:) yeni layihələr üçün üstünlük təşkil edir.
draw(_:) CPU-da icra olunur və optimallaşdırılmamış implementasiya kadr itkisinə və aşağı performansa səbəb ola bilər. Apple çəkməni sürətləndirmək üçün bir neçə sınaqdan keçmiş yanaşma tövsiyə edir.
Hər Core Graphics əməliyyatı (move(to:), addLine(to:), strokePath) əlavə yükə malikdir. Əməliyyatları qruplaşdırın və mürəkkəb fiqurlar üçün CGPath istifadə edin — yol bir dəfə yaradılır və hər draw(_:) çağırışında təkrar istifadə olunur.
UIBezierPath — CGPath üzərində Objective-C qabığıdır ki, fiqurlar yaratmaq üçün sadə API təqdim edir. UIBezierPath-i əvvəlcədən yaradın (məsələn, init-də) və draw(_:) daxilində sadəcə fill() və ya stroke() çağırın.
private let starPath: UIBezierPath = {
let path = UIBezierPath()
// Ulduz forması yaratmaq
path.move(to: CGPoint(x: 50, y: 0))
for i in 1...5 {
let angle = CGFloat(i) * 4 * CGFloat.pi / 5
path.addLine(to: CGPoint(x: 50 + 40 * cos(angle),
y: 50 + 40 * sin(angle)))
}
path.close()
return path
}()
override func draw(_ rect: CGRect) {
UIColor.systemYellow.setFill()
starPath.fill()
}
Proqramçılar draw(_:)-i yenidən təyin edərkən tez-tez eyni səhvlərə yol verirlər. Bu nümunələri bilmək səhvlərdən və performansın azalmasından qaçmağa kömək edir. Ən çox yayılmış problemlərə və onların həllərinə baxaq.
Bu qaydalara əməl etməklə, iOS altında istənilən layihədə xüsusi görünüşlərin sabit və sürətli çəkilməsini təmin edəcəksiniz. draw(_:)-i Instruments (Core Animation) vasitəsilə profilləşdirin ki, real icra müddətini və dar boğazları görəsiniz.
Tez-tez verilən suallar
Xeyr, birbaşa draw(_:) çağırışı Apple sənədləri tərəfindən qadağandır. Sistem özü çəkmə dövrünü idarə edir. Yenidən çəkmə tələb etmək üçün setNeedsDisplay() istifadə edin ki, bu da görünüşü ən yaxın render dövründə yenilənmə tələb edən kimi qeyd edir.
Funksional olaraq bu metodlar eynidir. drawRect: Objective-C-də, draw(_:) Swift-də istifadə olunur. Hər ikisi yenidən çəkmə sahəsinin CGRect-ni alır və UIGraphicsGetCurrentContext() vasitəsilə eyni Core Graphics kontekstindən istifadə edir.
Apple renderinqi optimallaşdırır: UIView-in yenidən təyin edilmiş draw(_:)-i yoxdursa, sistem onun üçün bitmap konteksti yaratmır. Bu yaddaşa qənaət edir. Yenidən təyin etmə varsa, lakin metod çağırılmırsa — görünüş çərçivəsinin sıfır olmadığını və görünüşün göründüyünü yoxlayın.
Yalnız lazım olduqda: ilk renderinq, setNeedsDisplay()-dən sonra, bounds dəyişdikdə contentMode = .redraw ilə. Statik vəziyyətdə draw(_:) təkrar çağırılmır ki, bu da CPU və batareya resurslarına qənaət edir.
Apple yenidən təyin edilmiş metodun əvvəlində super.draw(rect) çağırmağı tövsiyə edir. UIView-in cari implementasiyası boş olsa da, super çağırışı gələcək UIKit versiyaları ilə uyğunluğu təmin edir və yaxşı təcrübədir.
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