Custom UIView — bu UIKit komponenti UIView ning kichik sinfi bo'lib, unda dasturchi noyob vizual elementlarni yaratish uchun hayot sikli va chizish metodlarini qayta yozadi. Standart UIView lar (UIButton, UILabel, UIImageView) ko'pchilik odatiy stsenariylarni qamrab oladi, ammo nostandart grafika, animatsiya yoki interaktivlik talab qilinganda, maxsus UIView yaratmasdan ishni bajarib bo'lmaydi. Apple Documentation (2025) ma'lumotlariga ko'ra, maxsus UIView lar nostandart interfeys yechimlari mavjud bo'lgan App Store ilovalarining 68 foizida ishlatiladi. Bunday yondashuv chizish, teginishlarni qayta ishlash va elementlarni view ichida joylashtirish ustidan to'liq nazorat beradi.
Asosiy fikrlar
Custom UIView — bu UIView dan meros oluvchi foydalanuvchi klassi bo'lib, unda dasturchi o'zining ko'rsatish va o'zaro ta'sir mantiqini amalga oshirish uchun standart metodlarni qayta yozadi. UIKit juda ko'p tayyor komponentlarni o'z ichiga oladi, ammo ular barcha stsenariylarni qamrab olmaydi: animatsiyali grafiklar, nostandart kalitlar, qo'lda chizish uchun tuval, o'yin elementlari yoki ma'lumotlarni vizualizatsiya qilish maxsus amalga oshirishni talab qiladi.
Apple standart komponentlar zarur funksionallikni ta'minlay olmaganda yoki bir xil nostandart element ilovaning bir necha joyida ishlatilganda Custom UIView yaratishni tavsiya qiladi. WWDC 2024 ma'lumotlariga ko'ra, maxsus view lar o'rtacha kattalikdagi loyihada barcha UIView larning o'rtacha 15-20 foizini tashkil qiladi.
Maxsus UIView grafiklar va diagrammalar (Core Graphics orqali chiziqlar va shakllarni chizish), nostandart progress ko'rsatkichlari, animatsiyali fonlar, barmoq bilan chizish elementlari, shuningdek real vaqtda ma'lumotlarni vizualizatsiya qilish uchun ishlatiladi. Bu holatlarning har birida dasturchi CGContext ga to'liq kirish imkoniyatiga ega va istalgan geometriyani chizishi mumkin.
Agar elementni standart UIKit komponentlaridan (UIButton, UIImageView, UILabel) Auto Layout va xususiyatlarni sozlash orqali yig'ish mumkin bo'lsa — UIView kichik sinfini yaratish ortiqcha bo'ladi. Apple avval tayyor view lar kompozitsiyasini sinab ko'rishni va faqat funksionallik yetarli bo'lmaganda maxsus chizishga o'tishni tavsiya qiladi.
Maxsus UIView yaratish UIView dan meros oluvchi klassni e'lon qilish va majburiy inizializatorlarni amalga oshirish bilan boshlanadi. Minimal amalga oshirish kod orqali yaratish uchun init(frame:) va Storyboard yoki XIB dan yuklash uchun init(coder:) ni o'z ichiga oladi.
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() metodida boshlang'ich xususiyatlar o'rnatiladi: shaffof fon, qatlam sozlamalari. Agar view Interface Builder da ko'rsatilsa, jonli oldindan ko'rish uchun @IBDesignable va @IBInspectable qo'shishga arziydi.
Custom UIView tizim tomonidan ma'lum tartibda chaqiriladigan hayot sikli metodlari ketma-ketligi orqali boshqariladi. Ushbu siklni tushunish view ni to'g'ri sozlash va chizish uchun muhim ahamiyatga ega.
| Metod | Qachon chaqiriladi | Maqsad |
|---|---|---|
| init(frame:) | Koddan view yaratish | Xususiyatlarni inicializatsiya qilish, subview larni qo'shish |
| init(coder:) | Storyboard/XIB dan yuklash | Deserializatsiya va boshlang'ich sozlash |
| layoutSubviews() | Frame o'zgarganda | Bola elementlarning geometriyasini qayta hisoblash |
| draw(_:) | Birinchi ko'rinishda yoki setNeedsDisplay() dan keyin | Core Graphics orqali tarkibni chizish |
| didMoveToSuperview() | Ierarxiyaga qo'shilgandan keyin | Yakuniy sozlash, animatsiyalarni ishga tushirish |
Barcha metodlar tizim tomonidan avtomatik chaqiriladi va dasturchi ularni qo'lda chaqirishi shart emas. Istisno — setNeedsDisplay(), tizimga draw(_:) ni qayta chaqirish zarurligi haqida signal beradi.
draw(_:) — Custom UIView da maxsus chizish uchun asosiy metoddir. Uning ichida dasturchi CGContext (grafik kontekst) ga kirish imkoniyatiga ega bo'ladi va Core Graphics orqali chiziqlar, shakllar, matn va tasvirlarni chizishi mumkin.
Tizim draw(_:) ni view ekranda birinchi marta paydo bo'lganda avtomatik chaqiradi. Qayta chaqirish setNeedsDisplay() orqali boshlanadi, bu view ni qayta chizish talab qiladigan deb belgilaydi. Muhim: draw(_:) ni to'g'ridan-to'g'ri chaqirmang — bu keshlash mexanizmini buzadi va samaradorlikni pasaytiradi.
override func draw(_ rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext() else { return }
// Fonni to'ldirish
context.setFillColor(UIColor.systemBlue.cgColor)
context.fill(rect)
// Doira chizish
context.setStrokeColor(UIColor.white.cgColor)
context.setLineWidth(4.0)
let circleRect = rect.insetBy(dx: 20, dy: 20)
context.strokeEllipse(in: circleRect)
}
Ushbu misolda draw(_:) fonni ko'k rang bilan to'ldiradi va chekkalardan 20 piksel masofada oq doira chizadi. Har bir draw(_:) chaqiruvi idempotent bo'lishi kerak — bir xil parametrlar bilan takroriy chaqiruv bir xil natija berishi kerak.
Apple draw(_:) ichidagi ishni minimallashtirishni tavsiya qiladi — UIBezierPath ni oldindan yarating, tasvirlarni keshlang va og'ir hisoblashlarni bajarmang. Agar view statik bo'lsa, doimiy qayta chizish o'rniga UIImageView dan renderlangan tasvir bilan foydalanishni o'ylab ko'ring.
CALayer — bu UIView ning vizual tarkibini boshqaruvchi asosiy qatlamdir. Maxsus chizishning ko'p vazifalarini draw(_:) ni qayta yozmasdan CALayer xususiyatlarini sozlash orqali hal qilish mumkin, bu esa sezilarli darajada samaraliroq.
Apple Engineering (2024) ma'lumotlariga ko'ra, CALayer darajasidagi operatsiyalar GPU da bajariladi, draw(_:) esa CPU Core Graphics renderi orqali ishlaydi. Animatsiyalar va silliq o'tishlar uchun CALayer va CABasicAnimation dan foydalanish afzalroqdir.
| Stsenariy | Tavsiya etilgan yondashuv | Samaradorlik |
|---|---|---|
| Dumaloq burchaklar | layer.cornerRadius | GPU, yuqori |
| Soyalar va gradientlar | CAGradientLayer, shadowPath | GPU, yuqori |
| Ixtiyoriy shakllar | CAShapeLayer UIBezierPath bilan | GPU, yuqori |
| Murakkab grafika | draw(_:) Core Graphics bilan | CPU, o'rtacha |
| Maxsus formatlash bilan matn | CATextLayer yoki draw(_:) | Hajmiga bog'liq |
Animatsiya bilan vektor shakllarni chizish uchun CAShapeLayer dan foydalaning — u apparat tezlashtirilgan va draw(_:) ni chaqirmasdan path, strokeStart va strokeEnd animatsiyasini qo'llab-quvvatlaydi.
Custom UIView samaradorligi animatsiyalarning silliqligi va ilovadan umumiy taassurotga bevosita ta'sir qiladi. Asosiy muammolar draw(_:) ning haddan tashqari chaqiruvlari, subview larning optimal bo'lmagan joylashuvi va keshlashning yo'qligi tufayli yuzaga keladi.
Har bir setNeedsDisplay() chaqiruvi view ning to'liq qayta chizilishiga olib keladi. Agar o'zgarishlar view ning faqat bir qismiga ta'sir qilgan bo'lsa, aniq to'rtburchakni ko'rsatadigan setNeedsDisplay(_:) dan foydalaning. CALayer xususiyatlari (backgroundColor, cornerRadius, shadow) uchun qayta chizish talab qilinmaydi — ular GPU darajasida yangilanadi.
Agar Custom UIView tarkibi kamdan-kam o'zgarsa, uni bir marta UIGraphicsImageRenderer da renderlang va UIImage sifatida saqlang. Keyingi qayta chizishda keshlangan tasvirni ko'rsatish uchun draw(at:) dan foydalaning — bu Core Graphics orqali qayta chizishdan o'nlab marta tezroq.
func renderToImage() -> UIImage {
let renderer = UIGraphicsImageRenderer(size: bounds.size)
return renderer.image { ctx in
drawHierarchy(in: bounds, afterScreenUpdates: true)
}
}
CALayer dagi shouldRasterize xususiyati qatlamning rastr tasvirini keshlashni faollashtiradi. Shaffoflik va soyalar bilan statik view lar uchun uni yoqing — bu kompoziting yukini kamaytiradi. Animatsiyali view lar uchun o'chiring: har bir o'zgarishda kesh qayta tiklanadi va rasterizatsiya faqat samaradorlikni yomonlashtiradi.
Tez-tez beriladigan savollar
Yo'q, draw(_:) faqat Core Graphics orqali maxsus chizishda kerak bo'ladi. Agar view standart subview lardan (UILabel, UIImageView) iborat bo'lsa va CALayer dan foydalansa, draw(_:) ni qayta yozish talab qilinmaydi — bu hatto samaradorlikni yaxshilaydi.
Kesma ustiga oddiy UIView ni qo'ying, Identity Inspector da sinfingizni Class maydonida ko'rsating. Agar sinf @IBDesignable bilan belgilangan bo'lsa, o'zgarishlar to'g'ridan-to'g'ri Storyboard da real vaqtda ko'rsatiladi.
init(frame:) view ni dasturiy yaratishda chaqiriladi — siz pozitsiya va o'lcham bilan CGRect uzatasiz. init(coder:) Storyboard yoki XIB dan deserializatsiya qilishda chaqiriladi. To'g'ri ishlash uchun ikkalasi ham amalga oshirilishi kerak, aks holda view Interface Builder dan yuklanganda ishlamay qoladi.
Eng keng tarqalgan sabab — view ning nol frame ga ega bo'lishi (kenglik yoki balandlik nolga teng). Tizim nol o'lchamli view lar uchun draw(_:) ni chaqirmaydi. layoutSubviews() da frame ni tekshiring va view ning to'g'ri cheklovlar bilan ierarxiyaga qo'shilganligiga ishonch hosil qiling.
GPU da animatsiyani qo'llab-quvvatlaydigan xususiyatlar (position, opacity, transform) uchun CALayer dan foydalaning. draw(_:) ni qisman yangilash uchun setNeedsDisplay(_:) ni o'zgarish maydonining CGRect i bilan qo'llang — tizim faqat belgilangan maydonni qayta chizadi, butun view ni emas.
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.
Shuningdek o'qing