draw(_:) / drawRect UIView کلاس (Swift میں) کا ایک طریقہ ہے اور Objective-C میں اس کا ہم منصب (drawRect:) ہے، جو Core Graphics استعمال کرکے ویو کے مواد کو رینڈر کرنے کے لیے ذمہ دار ہے۔ سسٹم خود بخود اس طریقے کو کال کرتا ہے جب ویو پہلی بار اسکرین پر ظاہر ہوتا ہے اور setNeedsDisplay() کال کرنے کے بعد۔ Apple Documentation (2025) کے مطابق، draw(_:) واحد طریقہ ہے جہاں ڈیولپر کو کسٹم ڈرائنگ کے لیے موجودہ اسکرین کے گرافکس کانٹیکسٹ تک رسائی حاصل ہوتی ہے۔ draw(_:) کو اوور رائیڈ کرنا جزو کی ظاہری شکل پر مکمل کنٹرول دیتا ہے — سادہ ہندسی اشکال سے لے کر پیچیدہ اینی میٹڈ گرافکس تک۔
اہم نکات
draw(_:) UIView کا ایک instance طریقہ ہے جسے UIKit ویو کے مواد کو رینڈر کرنے کے لیے کال کرتا ہے۔ اس طریقے کے اندر، ڈیولپر کو CGContext گرافکس کانٹیکسٹ تک رسائی ملتی ہے اور وہ Core Graphics API استعمال کرکے لکیریں، بھرائی، متن اور تصاویر کھینچتا ہے۔ Objective-C میں drawRect: ایک ہی کام انجام دیتا ہے لیکن مختلف نحو کے ساتھ: واحد پیرامیٹر ایک CGRect ہے جو دوبارہ ڈرائنگ کے علاقے کی وضاحت کرتا ہے۔
Apple Engineering (2024) کے مطابق، draw(_:) CPU پر مبنی Bitmap Graphics Context رینڈرنگ کے ذریعے کام کرتا ہے، جو زیادہ سے زیادہ لچک فراہم کرتا ہے لیکن CALayer کے مقابلے میں زیادہ وسائل کی ضرورت ہوتی ہے۔ draw(_:) استعمال کرنے کا فیصلہ گرافکس کی پیچیدگی اور کارکردگی کی ضروریات کی بنیاد پر کیا جاتا ہے۔
Swift میں، طریقہ کو override func draw(_ rect: CGRect) کے طور پر اعلان کیا جاتا ہے، جہاں rect وہ مستطیل ہے جسے دوبارہ کھینچنے کی ضرورت ہے۔ Objective-C میں دستخط - (void)drawRect:(CGRect)rect ہے۔ setNeedsDisplay(_:) کے ذریعے جزوی دوبارہ ڈرائنگ کے دوران rect پیرامیٹر ویو کے bounds سے چھوٹا ہو سکتا ہے۔
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
CGContextFillRect(context, rect);
}
سسٹم خود بخود draw(_:) کو سختی سے طے شدہ منظرناموں میں کال کرتا ہے۔ ان محرکوں کو سمجھنا غیر ضروری دوبارہ ڈرائنگ سے بچنے اور ویو کی کارکردگی کو بہتر بنانے میں مدد کرتا ہے۔ ذیل میں طریقہ کے خودکار کال کے تمام معاملات درج ہیں۔
Apple دستاویزات خبردار کرتی ہیں: draw(_:) کو براہ راست کبھی نہ بلائیں۔ سسٹم خود فیصلہ کرتا ہے کہ کب ڈرائنگ کرنی ہے، اور براہ راست کال اندرونی کیشنگ میکانزم کو خراب کرتی ہے۔ دوبارہ ڈرائنگ کی درخواست کرنے کے لیے، ہمیشہ setNeedsDisplay() یا setNeedsDisplay(_:) استعمال کریں۔
Swift میں draw(_:) کو اوور رائیڈ کرنا گرافکس کانٹیکسٹ حاصل کرنے اور اس کے بعد Core Graphics کالز سے شروع ہوتا ہے۔ ڈرائنگ کے منطقی بلاکس کے لیے الگ الگ طریقے بنانے کی سفارش کی جاتی ہے — اس سے کوڈ کی پڑھنے کی اہلیت اور جانچ کی صلاحیت بہتر ہوتی ہے۔
override func draw(_ rect: CGRect) {
super.draw(rect)
guard let context = UIGraphicsGetCurrentContext() else { return }
// Line parameters
context.setStrokeColor(UIColor.darkGray.cgColor)
context.setLineWidth(2.0)
// Drawing a triangle
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()
}
اس مثال میں، draw(_:) 2 پکسل موٹی گہرے بھوری رنگ کی خاکہ کے ساتھ ایک مثلث کھینچتا ہے۔ طریقہ کے شروع میں super.draw(rect) کال کرنا Apple کی طرف سے تجویز کیا جاتا ہے تاکہ والدین کی ڈرائنگ منطق محفوظ رہے، اگرچہ UIView کا ڈیفالٹ draw(_:) نفاذ خالی ہے۔
draw(_:) کی ہر کال کو ایک جیسے ان پٹ ڈیٹا کے ساتھ ایک جیسا نتیجہ دینا چاہیے۔ یہ سسٹم کو نتیجہ کیش کرنے کی اجازت دیتا ہے اور اگر ویو کا مواد تبدیل نہیں ہوا ہے تو draw(_:) کو دوبارہ نہیں بلاتا۔ draw(_:) کے اندر بے ترتیب اقدار، سسٹم کا وقت یا نیٹ ورک کی درخواستیں استعمال نہ کریں۔
drawRect: تاریخی طور پر طریقہ کا پہلا ورژن ہے، جو iOS 2.0 میں Objective-C کے ساتھ ظاہر ہوا۔ Swift میں، طریقہ کا نام تبدیل کرکے draw(_:) کر دیا گیا جس میں بیرونی پیرامیٹر _ استعمال کیا گیا۔ عملی طور پر، طریقے ایک جیسے ہیں: دونوں دوبارہ ڈرائنگ کے علاقے کا CGRect وصول کرتے ہیں اور گرافکس کانٹیکسٹ تک رسائی کے لیے UIGraphicsGetCurrentContext() استعمال کرتے ہیں۔
| خصوصیت | draw(_:) (Swift) | drawRect: (Objective-C) |
|---|---|---|
| دستخط | override func draw(_ rect: CGRect) | - (void)drawRect:(CGRect)rect |
| super کال | super.draw(rect) | [super drawRect:rect] |
| کانٹیکسٹ | UIGraphicsGetCurrentContext() | UIGraphicsGetCurrentContext() |
| rect پیرامیٹر | rect: CGRect | CGRect rect |
| کارکردگی | یکساں | یکساں |
Objective-C سے Swift میں پروجیکٹ منتقل کرتے وقت، طریقہ کا نام تبدیل کرنا پہلے کاموں میں سے ایک ہے۔ Xcode ایک خودکار کنورٹر فراہم کرتا ہے، لیکن drawRect: کو دستی طور پر draw(_:) میں اپ ڈیٹ کرنے کی ضرورت ہے۔ Apple (2024) کے مطابق، Swift ورژن draw(_:) نئے پروجیکٹس کے لیے ترجیحی ہے۔
draw(_:) CPU پر چلتا ہے، اور ایک غیر موزوں نفاذ فریم ڈراپ اور ناقص کارکردگی کا سبب بن سکتا ہے۔ Apple ڈرائنگ کو تیز کرنے کے لیے کئی ثابت شدہ طریقوں کی سفارش کرتا ہے۔
ہر Core Graphics آپریشن (move(to:), addLine(to:), strokePath) میں اوور ہیڈ ہوتا ہے۔ آپریشنز کو گروپ کریں اور پیچیدہ اشکال کے لیے CGPath استعمال کریں — راستہ ایک بار بنایا جاتا ہے اور ہر draw(_:) کال پر دوبارہ استعمال ہوتا ہے۔
UIBezierPath CGPath پر ایک Objective-C ریپر ہے جو شکلیں بنانے کے لیے ایک سادہ API فراہم کرتا ہے۔ UIBezierPath کو پہلے سے بنائیں (مثال کے طور پر انیشیالائزر میں) اور draw(_:) کے اندر صرف fill() یا stroke() کال کریں۔
private let starPath: UIBezierPath = {
let path = UIBezierPath()
// Building a star shape
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()
}
ڈیولپرز اکثر draw(_:) کو اوور رائیڈ کرتے وقت ایک ہی غلطیاں کرتے ہیں۔ ان نمونوں کو جاننا بگز اور کارکردگی میں کمی سے بچنے میں مدد کرتا ہے۔ آئیے سب سے عام مسائل اور ان کے حل دیکھتے ہیں۔
ان اصولوں پر عمل کرتے ہوئے، آپ کسی بھی iOS پروجیکٹ میں مستحکم اور تیز کسٹم ویو ڈرائنگ کو یقینی بنائیں گے۔ اصل عملدرآمد کے وقت اور رکاوٹوں کو دیکھنے کے لیے Instruments (Core Animation) کے ذریعے draw(_:) کو پروفائل کریں۔
اکثر پوچھے گئے سوالات
نہیں، draw(_:) کی براہ راست کال Apple دستاویزات کے ذریعے ممنوع ہے۔ سسٹم خود ڈرائنگ سائیکل کا انتظام کرتا ہے۔ دوبارہ ڈرائنگ کی درخواست کرنے کے لیے setNeedsDisplay() استعمال کریں، جو قریب ترین رینڈرنگ سائیکل میں ویو کو اپ ڈیٹ کی ضرورت کے طور پر درست طریقے سے نشان زد کرتا ہے۔
عملی طور پر یہ طریقے ایک جیسے ہیں۔ drawRect: Objective-C میں استعمال ہوتا ہے، draw(_:) Swift میں۔ دونوں دوبارہ ڈرائنگ کے علاقے کا CGRect وصول کرتے ہیں اور UIGraphicsGetCurrentContext() کے ذریعے ایک ہی Core Graphics کانٹیکسٹ استعمال کرتے ہیں۔
Apple رینڈرنگ کو بہتر بناتا ہے: اگر UIView میں اوور رائیڈڈ draw(_:) نہیں ہے، سسٹم اس کے لیے bitmap کانٹیکسٹ نہیں بناتا۔ اس سے میموری بچتی ہے۔ اگر اوور رائیڈ موجود ہے لیکن طریقہ نہیں بلایا جاتا — چیک کریں کہ ویو کا فریم غیر صفر ہے اور ویو نظر آرہا ہے۔
صرف ضرورت ہونے پر: پہلا رینڈر، setNeedsDisplay() کے بعد، contentMode = .redraw کے ساتھ bounds تبدیل ہونے پر۔ جامد حالت میں، draw(_:) دوبارہ نہیں بلایا جاتا، CPU اور بیٹری کے وسائل بچاتا ہے۔
Apple اوور رائیڈڈ طریقہ کے شروع میں super.draw(rect) کال کرنے کی سفارش کرتا ہے۔ اگرچہ موجودہ UIView نفاذ خالی ہے، super کال مستقبل کے UIKit ورژنز کے ساتھ مطابقت کو یقینی بناتی ہے اور ایک اچھی مشق ہے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں