draw(_:) اور drawRect — یہ کیا ہے، کال اور اوور رائیڈنگ

مصنف: IT Sectr اشاعت: 2026-07-20 مطالعے کا وقت: 7 منٹ

draw(_:) / drawRect UIView کلاس (Swift میں) کا ایک طریقہ ہے اور Objective-C میں اس کا ہم منصب (drawRect:) ہے، جو Core Graphics استعمال کرکے ویو کے مواد کو رینڈر کرنے کے لیے ذمہ دار ہے۔ سسٹم خود بخود اس طریقے کو کال کرتا ہے جب ویو پہلی بار اسکرین پر ظاہر ہوتا ہے اور setNeedsDisplay() کال کرنے کے بعد۔ Apple Documentation (2025) کے مطابق، draw(_:) واحد طریقہ ہے جہاں ڈیولپر کو کسٹم ڈرائنگ کے لیے موجودہ اسکرین کے گرافکس کانٹیکسٹ تک رسائی حاصل ہوتی ہے۔ draw(_:) کو اوور رائیڈ کرنا جزو کی ظاہری شکل پر مکمل کنٹرول دیتا ہے — سادہ ہندسی اشکال سے لے کر پیچیدہ اینی میٹڈ گرافکس تک۔

اہم نکات

  • draw(_:) — Core Graphics کے ذریعے کسٹم ڈرائنگ کے لیے UIView طریقہ، ڈیولپر کے ذریعے براہ راست نہیں بلایا جاتا
  • drawRect: — Objective-C میں draw(_:) کا ہم منصب، نحوی طور پر مختلف، عملی طور پر ایک جیسا
  • CGContext — تمام ڈرائنگ آپریشنز کے لیے draw(_:) کے اندر دستیاب گرافکس کانٹیکسٹ
  • setNeedsDisplay() — ڈیولپر کی طرف سے draw(_:) کو دوبارہ ڈرائنگ کی درخواست کرنے کا واحد صحیح طریقہ
  • UIGraphicsGetCurrentContext() — draw(_:) کے اندر موجودہ کانٹیکسٹ حاصل کرنے کا فنکشن، ڈرائنگ سے پہلے لازمی مرحلہ

draw(_:) / drawRect کیا ہے

draw(_:) UIView کا ایک instance طریقہ ہے جسے UIKit ویو کے مواد کو رینڈر کرنے کے لیے کال کرتا ہے۔ اس طریقے کے اندر، ڈیولپر کو CGContext گرافکس کانٹیکسٹ تک رسائی ملتی ہے اور وہ Core Graphics API استعمال کرکے لکیریں، بھرائی، متن اور تصاویر کھینچتا ہے۔ Objective-C میں drawRect: ایک ہی کام انجام دیتا ہے لیکن مختلف نحو کے ساتھ: واحد پیرامیٹر ایک CGRect ہے جو دوبارہ ڈرائنگ کے علاقے کی وضاحت کرتا ہے۔

Apple Engineering (2024) کے مطابق، draw(_:) CPU پر مبنی Bitmap Graphics Context رینڈرنگ کے ذریعے کام کرتا ہے، جو زیادہ سے زیادہ لچک فراہم کرتا ہے لیکن CALayer کے مقابلے میں زیادہ وسائل کی ضرورت ہوتی ہے۔ draw(_:) استعمال کرنے کا فیصلہ گرافکس کی پیچیدگی اور کارکردگی کی ضروریات کی بنیاد پر کیا جاتا ہے۔

Swift اور Objective-C میں طریقہ کے دستخط

Swift میں، طریقہ کو override func draw(_ rect: CGRect) کے طور پر اعلان کیا جاتا ہے، جہاں rect وہ مستطیل ہے جسے دوبارہ کھینچنے کی ضرورت ہے۔ Objective-C میں دستخط - (void)drawRect:(CGRect)rect ہے۔ setNeedsDisplay(_:) کے ذریعے جزوی دوبارہ ڈرائنگ کے دوران rect پیرامیٹر ویو کے bounds سے چھوٹا ہو سکتا ہے۔

objective-c
- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
    CGContextFillRect(context, rect);
}

سسٹم draw(_:) کو کب کال کرتا ہے

سسٹم خود بخود draw(_:) کو سختی سے طے شدہ منظرناموں میں کال کرتا ہے۔ ان محرکوں کو سمجھنا غیر ضروری دوبارہ ڈرائنگ سے بچنے اور ویو کی کارکردگی کو بہتر بنانے میں مدد کرتا ہے۔ ذیل میں طریقہ کے خودکار کال کے تمام معاملات درج ہیں۔

  • پہلا رینڈر — جب ویو پہلی بار درجہ بندی میں شامل ہوتا ہے اور اسکرین پر نظر آنے لگتا ہے
  • setNeedsDisplay() — اس طریقہ کو کال کرنے کے بعد، سسٹم اگلے ڈرائنگ سائیکل میں دوبارہ کھینچتا ہے
  • setNeedsDisplay(_:) — اوپر کی طرح، لیکن دوبارہ ڈرائنگ کے لیے ایک مخصوص مستطیل کی وضاحت کرتا ہے
  • contentMode — جب bounds تبدیل ہوتے ہیں، اگر contentMode کو دوبارہ ڈرائنگ کی ضرورت ہوتی ہے (مثال .redraw)
  • setNeedsLayout() — بعض صورتوں میں، ذیلی ویوز کی دوبارہ ترتیب کے بعد، دوبارہ ڈرائنگ ضروری ہو سکتی ہے

Apple دستاویزات خبردار کرتی ہیں: draw(_:) کو براہ راست کبھی نہ بلائیں۔ سسٹم خود فیصلہ کرتا ہے کہ کب ڈرائنگ کرنی ہے، اور براہ راست کال اندرونی کیشنگ میکانزم کو خراب کرتی ہے۔ دوبارہ ڈرائنگ کی درخواست کرنے کے لیے، ہمیشہ setNeedsDisplay() یا setNeedsDisplay(_:) استعمال کریں۔

Swift میں draw(_:) کو کیسے اوور رائیڈ کریں

Swift میں draw(_:) کو اوور رائیڈ کرنا گرافکس کانٹیکسٹ حاصل کرنے اور اس کے بعد Core Graphics کالز سے شروع ہوتا ہے۔ ڈرائنگ کے منطقی بلاکس کے لیے الگ الگ طریقے بنانے کی سفارش کی جاتی ہے — اس سے کوڈ کی پڑھنے کی اہلیت اور جانچ کی صلاحیت بہتر ہوتی ہے۔

swift
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(_:) کا idempotency اصول

draw(_:) کی ہر کال کو ایک جیسے ان پٹ ڈیٹا کے ساتھ ایک جیسا نتیجہ دینا چاہیے۔ یہ سسٹم کو نتیجہ کیش کرنے کی اجازت دیتا ہے اور اگر ویو کا مواد تبدیل نہیں ہوا ہے تو draw(_:) کو دوبارہ نہیں بلاتا۔ draw(_:) کے اندر بے ترتیب اقدار، سسٹم کا وقت یا نیٹ ورک کی درخواستیں استعمال نہ کریں۔

Objective-C میں drawRect: اور 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: CGRectCGRect rect
کارکردگییکساںیکساں

Objective-C سے Swift میں پروجیکٹ منتقل کرتے وقت، طریقہ کا نام تبدیل کرنا پہلے کاموں میں سے ایک ہے۔ Xcode ایک خودکار کنورٹر فراہم کرتا ہے، لیکن drawRect: کو دستی طور پر draw(_:) میں اپ ڈیٹ کرنے کی ضرورت ہے۔ Apple (2024) کے مطابق، Swift ورژن draw(_:) نئے پروجیکٹس کے لیے ترجیحی ہے۔

draw(_:) میں ڈرائنگ کی اصلاح

draw(_:) CPU پر چلتا ہے، اور ایک غیر موزوں نفاذ فریم ڈراپ اور ناقص کارکردگی کا سبب بن سکتا ہے۔ Apple ڈرائنگ کو تیز کرنے کے لیے کئی ثابت شدہ طریقوں کی سفارش کرتا ہے۔

ڈرائنگ آپریشنز کی تعداد کو کم سے کم کریں

ہر Core Graphics آپریشن (move(to:), addLine(to:), strokePath) میں اوور ہیڈ ہوتا ہے۔ آپریشنز کو گروپ کریں اور پیچیدہ اشکال کے لیے CGPath استعمال کریں — راستہ ایک بار بنایا جاتا ہے اور ہر draw(_:) کال پر دوبارہ استعمال ہوتا ہے۔

ویکٹر اشیاء کے لیے UIBezierPath استعمال کریں

UIBezierPath CGPath پر ایک Objective-C ریپر ہے جو شکلیں بنانے کے لیے ایک سادہ API فراہم کرتا ہے۔ UIBezierPath کو پہلے سے بنائیں (مثال کے طور پر انیشیالائزر میں) اور draw(_:) کے اندر صرف fill() یا stroke() کال کریں۔

swift
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(_:) کے ساتھ کام کرتے وقت عام غلطیاں

ڈیولپرز اکثر draw(_:) کو اوور رائیڈ کرتے وقت ایک ہی غلطیاں کرتے ہیں۔ ان نمونوں کو جاننا بگز اور کارکردگی میں کمی سے بچنے میں مدد کرتا ہے۔ آئیے سب سے عام مسائل اور ان کے حل دیکھتے ہیں۔

  • draw(_:) کو براہ راست کال کرنا — draw(_:) کو براہ راست کبھی نہ بلائیں۔ دوبارہ ڈرائنگ کی درخواست کرنے کے لیے setNeedsDisplay() استعمال کریں۔ براہ راست کال کیشنگ کو توڑ دیتی ہے اور غلط ڈسپلے کا سبب بن سکتی ہے۔
  • draw(_:) کے اندر بھاری حسابات — draw(_:) جتنا ممکن ہو ہلکا ہونا چاہیے۔ UIBezierPath، تصاویر اور دیگر بھاری اشیاء کو طریقہ کے باہر بنائیں، انہیں ایک بار انیشیالائز کریں۔
  • draw(_:) کے اندر اشیاء بنانا — draw(_:) کے اندر UIColor، UIFont اور UIGraphicsImageRenderer کی تعمیر میموری پر غیر ضروری بوجھ ڈالتی ہے۔ اشیاء کی تخلیق کو کلاس پراپرٹیز میں منتقل کریں۔
  • rect پیرامیٹر کو نظر انداز کرنا — rect اس علاقے کی وضاحت کرتا ہے جسے دوبارہ کھینچنے کی ضرورت ہے۔ rect کے باہر ڈرائنگ سسٹم کے ذریعے رد کر دی جاتی ہے لیکن وسائل استعمال کرتی ہے۔ ڈرائنگ سے پہلے rect کے ساتھ انٹرسیکشن چیک کریں۔
  • super.draw(rect) کی کمی — اگرچہ UIView کا نفاذ خالی ہے، Apple مستقبل کی UIKit تبدیلیوں کے ساتھ مطابقت کے لیے super.draw(rect) کال کرنے کی سفارش کرتا ہے۔

ان اصولوں پر عمل کرتے ہوئے، آپ کسی بھی iOS پروجیکٹ میں مستحکم اور تیز کسٹم ویو ڈرائنگ کو یقینی بنائیں گے۔ اصل عملدرآمد کے وقت اور رکاوٹوں کو دیکھنے کے لیے Instruments (Core Animation) کے ذریعے draw(_:) کو پروفائل کریں۔

اکثر پوچھے گئے سوالات

کیا draw(_:) کو براہ راست کال کیا جا سکتا ہے؟

نہیں، draw(_:) کی براہ راست کال Apple دستاویزات کے ذریعے ممنوع ہے۔ سسٹم خود ڈرائنگ سائیکل کا انتظام کرتا ہے۔ دوبارہ ڈرائنگ کی درخواست کرنے کے لیے setNeedsDisplay() استعمال کریں، جو قریب ترین رینڈرنگ سائیکل میں ویو کو اپ ڈیٹ کی ضرورت کے طور پر درست طریقے سے نشان زد کرتا ہے۔

drawRect: draw(_:) سے کیسے مختلف ہے؟

عملی طور پر یہ طریقے ایک جیسے ہیں۔ drawRect: Objective-C میں استعمال ہوتا ہے، draw(_:) Swift میں۔ دونوں دوبارہ ڈرائنگ کے علاقے کا CGRect وصول کرتے ہیں اور UIGraphicsGetCurrentContext() کے ذریعے ایک ہی Core Graphics کانٹیکسٹ استعمال کرتے ہیں۔

خالی UIView کے لیے draw(_:) کیوں نہیں بلایا جاتا؟

Apple رینڈرنگ کو بہتر بناتا ہے: اگر UIView میں اوور رائیڈڈ draw(_:) نہیں ہے، سسٹم اس کے لیے bitmap کانٹیکسٹ نہیں بناتا۔ اس سے میموری بچتی ہے۔ اگر اوور رائیڈ موجود ہے لیکن طریقہ نہیں بلایا جاتا — چیک کریں کہ ویو کا فریم غیر صفر ہے اور ویو نظر آرہا ہے۔

سسٹم کتنی بار draw(_:) کو کال کرتا ہے؟

صرف ضرورت ہونے پر: پہلا رینڈر، setNeedsDisplay() کے بعد، contentMode = .redraw کے ساتھ bounds تبدیل ہونے پر۔ جامد حالت میں، draw(_:) دوبارہ نہیں بلایا جاتا، CPU اور بیٹری کے وسائل بچاتا ہے۔

کیا Swift میں super.draw(rect) کال کرنا ضروری ہے؟

Apple اوور رائیڈڈ طریقہ کے شروع میں super.draw(rect) کال کرنے کی سفارش کرتا ہے۔ اگرچہ موجودہ UIView نفاذ خالی ہے، super کال مستقبل کے UIKit ورژنز کے ساتھ مطابقت کو یقینی بناتی ہے اور ایک اچھی مشق ہے۔

خلاصہ

  • draw(_:) / drawRect — Swift اور Objective-C میں UIView کا بنیادی ڈرائنگ طریقہ، سسٹم کے ذریعے خودکار طور پر بلایا جاتا ہے
  • CGContext — UIGraphicsGetCurrentContext() کے ذریعے draw(_:) کے اندر دستیاب Core Graphics کانٹیکسٹ
  • setNeedsDisplay() — دوبارہ ڈرائنگ کی درخواست کرنے کا صحیح طریقہ؛ draw(_:) کو براہ راست کال کرنا ممنوع ہے
  • Idempotency — مناسب کیشنگ کے لیے draw(_:) کو ایک جیسے ان پٹ ڈیٹا کے ساتھ ایک جیسا نتیجہ دینا چاہیے
  • UIBezierPath — ہر کال پر CPU بوجھ کم کرنے کے لیے draw(_:) کے باہر راستے بنائیں
  • rect پیرامیٹر — دوبارہ ڈرائنگ کا علاقہ رکھتا ہے؛ اصلاح کے لیے انٹرسیکشن استعمال کریں — اس کے باہر نہ کھینچیں
  • پروفائلنگ — سست آپریشنز کی شناخت کے لیے Instruments Core Animation کے ذریعے draw(_:) کی کارکردگی چیک کریں

ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے

IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔

پروجیکٹ پر بحث کریں

مزید پڑھیں