draw(_:) / drawRect — bu UIView sinifining (Swift-da) va uning Objective-C-dagi (drawRect:) analogi bo'lgan, Core Graphics yordamida ko'rinish tarkibini chizish uchun javob beradigan metoddir. Tizim bu metodni ko'rinish ekranda birinchi marta paydo bo'lganda va setNeedsDisplay() chaqirilgandan so'ng avtomatik chaqiradi. Apple Documentation (2025) ma'lumotlariga ko'ra, draw(_:) dasturchiga maxsus chizish uchun joriy ekranning grafik kontekstiga kirish imkoniyati mavjud bo'lgan yagona usuldir. draw(_:) ni qayta belgilash komponentning tashqi ko'rinishi ustidan to'liq nazorat beradi — oddiy geometrik shakllardan tortib murakkab animatsiyali grafikagacha.
Asosiy
draw(_:) — UIKit ko'rinish tarkibini render qilish uchun chaqiradigan UIView namunaviy metodi. Bu metod ichida dasturchi CGContext grafik kontekstiga kirish imkoniyatiga ega bo'ladi va chiziqlar, to'ldirishlar, matn va tasvirlarni chizish uchun Core Graphics API dan foydalanadi. Objective-C-dagi drawRect: bir xil funktsiyani bajaradi, lekin boshqa sintaksis bilan: yagona parametr — qayta chiziladigan maydonni belgilaydigan CGRect.
Apple Engineering (2024) ma'lumotlariga ko'ra, draw(_:) CPU renderlash Bitmap Graphics Context orqali ishlaydi, bu maksimal moslashuvchanlikni ta'minlaydi, lekin CALayer bilan solishtirganda ko'proq resurslarni talab qiladi. draw(_:) dan foydalanish to'g'risidagi qaror grafika murakkabligi va ishlash talablariga asoslanadi.
Swift-da metod override func draw(_ rect: CGRect) sifatida e'lon qilinadi, bu yerda rect qayta chizilishi kerak bo'lgan to'rtburchakdir. Objective-C-da imzo - (void)drawRect:(CGRect)rect. rect parametri setNeedsDisplay(_:) orqali qisman qayta chizish vaqtida ko'rinishning bounds dan kichikroq bo'lishi mumkin.
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
CGContextFillRect(context, rect);
}
Tizim draw(_:) ni qat'iy belgilangan stsenariylarda avtomatik chaqiradi. Ushbu tetiklarni tushunish keraksiz qayta chizishlardan qochish va ko'rinish ishlashini optimallashtirishga yordam beradi. Quyida metodning avtomatik chaqirilishining barcha holatlari keltirilgan.
Apple hujjatlari ogohlantiradi: hech qachon draw(_:) ni to'g'ridan-to'g'ri chaqirmang. Tizim o'zi chizishni qachon bajarishni hal qiladi va to'g'ridan-to'g'ri chaqirish ichki keshlash mexanizmini buzadi. Qayta chizishni so'rash uchun har doim setNeedsDisplay() yoki setNeedsDisplay(_:) dan foydalaning.
Swift-da draw(_:) ni qayta belgilash grafik kontekstni olish va keyingi Core Graphics chaqiruvlari bilan boshlanadi. Chizishning mantiqiy bloklari uchun alohida metodlar yaratish tavsiya etiladi — bu kod o'qiluvchanligi va test qilinishini yaxshilaydi.
override func draw(_ rect: CGRect) {
super.draw(rect)
guard let context = UIGraphicsGetCurrentContext() else { return }
// Chiziq parametrlari
context.setStrokeColor(UIColor.darkGray.cgColor)
context.setLineWidth(2.0)
// Uchburchak chizish
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()
}
Ushbu misolda draw(_:) 2 piksel qalinlikdagi to'q kulrang kontur bilan uchburchak chizadi. super.draw(rect) ni metod boshida chaqirish Apple tomonidan ota-ona chizish mantiqini saqlab qolish uchun tavsiya etiladi, garchi UIView-dagi draw(_:) ning standart implementatsiyasi bo'sh bo'lsa ham.
draw(_:) ning har bir chaqiruvi bir xil kirish ma'lumotlari bilan bir xil natija berishi kerak. Bu tizimga natijani keshlash va ko'rinish tarkibi o'zgarmagan bo'lsa, draw(_:) ni qayta chaqirmaslik imkonini beradi. draw(_:) ichida tasodifiy qiymatlar, tizim vaqti yoki tarmoq so'rovlaridan foydalanmang.
drawRect: — tarixan iOS 2.0 bilan Objective-C bilan birga paydo bo'lgan metodning birinchi variantidir. Swift-da metod tashqi parametr _ yordamida draw(_:) deb nomlandi. Funksional jihatdan metodlar bir xil: ikkalasi ham qayta chizish maydonining CGRect-ni oladi va grafik kontekstga kirish uchun UIGraphicsGetCurrentContext() dan foydalanadi.
| Xususiyat | draw(_:) (Swift) | drawRect: (Objective-C) |
|---|---|---|
| Imzo | override func draw(_ rect: CGRect) | - (void)drawRect:(CGRect)rect |
| Super chaqiruvi | super.draw(rect) | [super drawRect:rect] |
| Kontekst | UIGraphicsGetCurrentContext() | UIGraphicsGetCurrentContext() |
| Parametr rect | rect: CGRect | CGRect rect |
| Ishlash | Bir xil | Bir xil |
Loyihani Objective-C dan Swift ga migratsiya qilishda metodni qayta nomlash birinchi vazifalardan biridir. Xcode avtomatik konvertorni taqdim etadi, ammo drawRect: draw(_:) ga qo'lda yangilanishni talab qiladi. Apple (2024) ma'lumotlariga ko'ra, Swift versiyasi draw(_:) yangi loyihalar uchun afzal hisoblanadi.
draw(_:) CPU-da bajariladi va optimallashtirilmagan implementatsiya kadr tushishi va past ishlashga sabab bo'lishi mumkin. Apple chizishni tezlashtirish uchun bir nechta tasdiqlangan yondashuvlarni tavsiya qiladi.
Har bir Core Graphics operatsiyasi (move(to:), addLine(to:), strokePath) qo'shimcha yukga ega. Operatsiyalarni guruhlang va murakkab shakllar uchun CGPath dan foydalaning — yo'l bir marta yaratiladi va har bir draw(_:) chaqiruvida qayta ishlatiladi.
UIBezierPath — bu CGPath ustidagi Objective-C qobig'i bo'lib, shakllar yaratish uchun oddiy API taqdim etadi. UIBezierPath ni oldindan yarating (masalan, initsializatorda) va draw(_:) ichida shunchaki fill() yoki stroke() ni chaqiring.
private let starPath: UIBezierPath = {
let path = UIBezierPath()
// Yulduz shaklini yaratish
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()
}
Dasturchilar ko'pincha draw(_:) ni qayta belgilashda bir xil xatolarga yo'l qo'yadilar. Ushbu naqshlarni bilish xatolar va ishlashning pasayishidan qochishga yordam beradi. Eng keng tarqalgan muammolar va ularning yechimlarini ko'rib chiqaylik.
Ushbu qoidalarga rioya qilgan holda, siz iOS-dagi har qanday loyihada maxsus ko'rinishlarning barqaror va tez chizilishini ta'minlaysiz. draw(_:) ni Instruments (Core Animation) orqali profiling qiling haqiqiy bajarilish vaqti va tor joylarni ko'rish uchun.
Tez-tez beriladigan savollar
Yo'q, draw(_:) ni to'g'ridan-to'g'ri chaqirish Apple hujjatlari tomonidan taqiqlangan. Tizim o'zi chizish siklini boshqaradi. Qayta chizishni so'rash uchun setNeedsDisplay() dan foydalaning, u ko'rinishni eng yaqin renderlash siklida yangilanishi kerak deb to'g'ri belgilaydi.
Funksional jihatdan bu metodlar bir xil. drawRect: Objective-C da, draw(_:) Swift da ishlatiladi. Ikkalasi ham qayta chizish maydonining CGRect-ni oladi va UIGraphicsGetCurrentContext() orqali bir xil Core Graphics kontekstidan foydalanadi.
Apple renderlashni optimallashtiradi: agar UIView-da qayta belgilangan draw(_:) bo'lmasa, tizim uning uchun bitmap kontekst yaratmaydi. Bu xotirani tejaydi. Agar qayta belgilash mavjud bo'lsa, lekin metod chaqirilmasa — ko'rinish ramkasi nol emasligini va ko'rinish ko'rinadiganligini tekshiring.
Faqat kerak bo'lganda: birinchi renderlash, setNeedsDisplay() dan so'ng, bounds o'zgarganda contentMode = .redraw bilan. Statik holatda draw(_:) qayta chaqirilmaydi, bu CPU va batareya resurslarini tejaydi.
Apple qayta belgilangan metod boshida super.draw(rect) ni chaqirishni tavsiya qiladi. UIView ning joriy implementatsiyasi bo'sh bo'lsa ham, super chaqiruvi kelajakdagi UIKit versiyalari bilan moslikni ta'minlaydi va yaxshi amaliyotdir.
Xulosa
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.