setNeedsDisplay(): طریقہ کار کا جوهر اور iOS میں دوبارہ ڈرائنگ کا میکانزم

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

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

اہم نکات

  • setNeedsDisplay() — UIView کے لیے ایک التوا شدہ دوبارہ ڈرائنگ کی درخواست، draw(_:) کو ہم وقت نہیں بلاتا
  • dirty فلیگ — ایک اندرونی ویو فلیگ جو setNeedsDisplay() کے ذریعے سیٹ کیا جاتا ہے اور draw(_:) کے بعد صاف ہوتا ہے
  • setNeedsDisplay(_:) — صرف مخصوص علاقے کی جزوی دوبارہ ڈرائنگ کے لیے CGRect کے ساتھ ایک اوورلوڈ
  • displayIfNeeded() — جبری ہم وقت دوبارہ ڈرائنگ، فوری اپ ڈیٹس کے لیے استعمال ہوتا ہے
  • رینڈرنگ سائیکل — سسٹم run loop کے آخر میں dirty ویوز کو پروسیس کرتا ہے، متعدد درخواستوں کو ایک پاس میں یکجا کرتا ہے

setNeedsDisplay() کیا ہے

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

اہم خصوصیت غیر ہم وقتی ہے۔ ایک ہی ویو کے لیے لگاتار متعدد setNeedsDisplay() کالیں draw(_:) کی متعدد کالوں کا نتیجہ نہیں دیں گی — سسٹم انہیں ایک آپریشن میں یکجا کرتا ہے۔ یہ کارکردگی کے لیے انتہائی اہم ہے: اگر کوئی ویو پراپرٹی فی فریم کئی بار بدلتی ہے، تو draw(_:) صرف ایک بار کال ہوتا ہے۔

التوا شدہ دوبارہ ڈرائنگ کیسے کام کرتی ہے

التوا شدہ دوبارہ ڈرائنگ کا میکانزم UIKit رینڈرنگ سائیکل پر مبنی ہے۔ جب setNeedsDisplay() کال کیا جاتا ہے، سسٹم اندرونی فلیگ layer.needsDisplay کو true پر سیٹ کرتا ہے۔ موجودہ run loop کے آخر میں، سسٹم تمام dirty لیئرز کا چکر لگاتا ہے اور ہر ایک کے لیے draw(_:) کال کرتا ہے۔

Run loop اور رینڈرنگ مراحل

UIKit run loop میں ایک اپ ڈیٹ مرحلہ شامل ہے جس کے دوران dirty ویوز پروسیس ہوتی ہیں۔ اس مرحلے میں، اگر ضرورت ہو تو layoutSubviews() کال کیا جاتا ہے، پھر تمام نشان زدہ ویوز کے لیے draw(_:) کال کیا جاتا ہے۔ ڈرائنگ مکمل ہونے کے بعد، نتیجہ کمپوزٹنگ کے لیے Core Animation کے ذریعے GPU کو بھیجا جاتا ہے۔

swift
class ProgressView: UIView {
    var progress: CGFloat = 0 {
        didSet {
            setNeedsDisplay()
        }
    }

    override func draw(_ rect: CGRect) {
        super.draw(rect)
        guard let ctx = UIGraphicsGetCurrentContext() else { return }

        // پس منظر
        ctx.setFillColor(UIColor.lightGray.cgColor)
        ctx.fill(rect)

        // اقدام کا بار
        let fillRect = CGRect(x: rect.minX, y: rect.minY,
                              width: rect.width * progress, height: rect.height)
        ctx.setFillColor(UIColor.systemGreen.cgColor)
        ctx.fill(fillRect)
    }
}

اس مثال میں، progressView progress کو اپ ڈیٹ کرتا ہے، اور ہر سیٹر خود بخود setNeedsDisplay() کال کرتا ہے۔ سسٹم run loop کے ختم ہونے کا انتظار کرتا ہے اور حقیقی progress ویلیو کے ساتھ draw(_:) کال کرتا ہے۔ اگر progress فی فریم تین بار بدلتا ہے، تو draw(_:) صرف ایک بار عمل میں آتا ہے — آخری ویلیو کے ساتھ۔

setNeedsDisplay() بمقابلہ setNeedsDisplay(_:)

setNeedsDisplay(_:) طریقہ CGRect قسم کا rect پیرامیٹر لیتا ہے، جو دوبارہ ڈرائنگ کے علاقے کو محدود کرتا ہے۔ یہ پورے ویو کے بجائے صرف تبدیل شدہ حصے کو دوبارہ ڈرا کرنے کی اجازت دیتا ہے۔ کارکردگی کا فرق بڑے ویوز کے ساتھ کام کرتے ہوئے نمایاں ہو جاتا ہے جہاں تبدیلیاں چھوٹے علاقے کو متاثر کرتی ہیں۔

خصوصیتsetNeedsDisplay()setNeedsDisplay(_:)
پیرامیٹرکوئی نہیںCGRect — دوبارہ ڈرائنگ کا علاقہ
دوبارہ ڈرائنگ کا علاقہپورے ویو کے boundsصرف مخصوص مستطیل
کارکردگیبڑے ویوز میں کمجزوی تبدیلیوں میں زیادہ
draw(_:) میں rect پیرامیٹرپورے boundsمخصوص مستطیل
کب استعمال کریںپورے مواد کی تبدیلینکاتی تبدیلیاں (کرسر، نمایاں)

پیچیدہ گرافکس کے لیے، پہلے پورے منظر کو آف اسکرین سیاق و سباق میں ڈرا کرنے کی سفارش کی جاتی ہے، پھر صرف تبدیل شدہ علاقے کے لیے setNeedsDisplay(_:) کال کریں۔ یہ iOS پر ڈرائنگ ایپلیکیشنز اور گرافک ایڈیٹرز میں ایک معیاری تکنیک ہے۔

displayIfNeeded() مقابل setNeedsDisplay()

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

Apple صرف انتہائی صورتوں میں displayIfNeeded() استعمال کرنے کی سفارش کرتا ہے جب ڈرائنگ کا نتیجہ فوری طور پر درکار ہو — مثال کے طور پر، اسکرین شاٹ لینے سے پہلے یا UIGraphicsImageRenderer کے لیے ہم وقت تصویر کی تخلیق کے دوران۔ عام منظرناموں میں، setNeedsDisplay() کے ذریعے غیر ہم وقتی ماڈل ترجیحی ہے کیونکہ یہ مرکزی تھریڈ کو مسدود نہیں کرتا۔

swift
    // غیر ہم وقت — تجویز شدہ
someView.setNeedsDisplay()

    // ہم وقت — صرف ضرورت کی صورت میں
someView.setNeedsDisplay()
someView.displayIfNeeded() // draw(_:) فورا بلایا گیا

پہلے setNeedsDisplay() کے بغیر displayIfNeeded() کال کرنے کا کوئی اثر نہیں ہوگا — طریقہ صرف پہلے سے dirty نشان زدہ ویوز کو پروسیس کرتا ہے۔ اگر کسی ویو کو دوبارہ ڈرائنگ کی ضرورت نہیں ہے، تو displayIfNeeded() draw(_:) کال کیے بغیر مکمل ہو جاتا ہے۔

setNeedsDisplay() کالوں کی اصلاح

بار بار setNeedsDisplay() کالیں کارکردگی کو کم کر سکتی ہیں، خاص طور پر اینیمیشن کے دوران۔ آئیے اہم اصلاحی حکمت عملیوں پر نظر ڈالتے ہیں۔

ماڈل کے ذریعے تبدیلیوں کو گروپ کرنا

ہر انفرادی پراپرٹی کی تبدیلی پر setNeedsDisplay() کال کرنے کے بجائے، تبدیلیوں کو جمع کریں اور تمام اپ ڈیٹس لاگو کرنے کے بعد ایک بار طریقہ کال کریں۔ مثال کے طور پر، کسی عنصر کا رنگ، سائز اور پوزیشن تبدیل کرتے وقت — تمام پراپرٹیز سیٹ کرنے کے بعد ایک بار setNeedsDisplay() کال کریں۔

اینیمیٹیبل پراپرٹیز کے لیے CALayer کا استعمال

اگر کوئی پراپرٹی CALayer (backgroundColor, opacity, position, transform) کے ذریعے اینیمیٹ کی جا سکتی ہے، تو draw(_:) کے بجائے Core Animation استعمال کریں۔ CALayer پراپرٹیز draw(_:) کال کیے بغیر GPU پر اپ ڈیٹ ہوتی ہیں، CPU بوجھ کے بغیر 60 FPS فراہم کرتی ہیں۔

CATransaction کے ذریعے بیچ اپ ڈیٹ

متعدد تبدیلیوں کو ایک رینڈرنگ پاس میں گروپ کرنے کے لیے CATransaction استعمال کریں۔ یہ متعدد setNeedsDisplay() کالوں کو لین دین کے آخر میں ایک draw(_:) آپریشن میں یکجا کرنے کی اجازت دیتا ہے۔

swift
CATransaction.begin()
CATransaction.setDisableActions(true)

view1.setNeedsDisplay()
view2.setNeedsDisplay()
view3.setNeedsDisplay()

CATransaction.commit()

displayIfNeeded() کا زیادہ استعمال نہ کریں — ہم وقت دوبارہ ڈرائنگ مرکزی تھریڈ کو مسدود کرتی ہے اور فریم ڈراپ کا سبب بن سکتی ہے۔ اسے صرف ان آپریشنز کے لیے استعمال کریں جہاں موجودہ run loop ختم ہونے سے پہلے ڈرائنگ کا نتیجہ اہم ہو۔

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

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

نہیں، براہ راست draw(_:) کال کرنا ممنوع ہے۔ setNeedsDisplay() ویو کو dirty کے طور پر صحیح طریقے سے نشان زد کرتا ہے، اور سسٹم رینڈرنگ سائیکل کے مناسب وقت پر draw(_:) کال کرتا ہے۔ براہ راست draw(_:) کال کرنا کیشنگ میکانزم کو نظر انداز کرتا ہے اور غیر مطابقت پذیر حالت کا باعث بن سکتا ہے۔

setNeedsDisplay() کی متعدد کالوں سے کیا ہوتا ہے؟

ایک ہی ویو کے لیے setNeedsDisplay() کی متعدد کالیں سسٹم کے ذریعے ایک draw(_:) کال میں یکجا کر دی جاتی ہیں۔ یہ اس لیے ہوتا ہے کیونکہ طریقہ صرف dirty فلیگ سیٹ کرتا ہے، جو run loop کے آخر میں draw(_:) کے حقیقی نفاذ کے بعد ہی صاف ہوتا ہے۔

setNeedsDisplay() setNeedsLayout() سے کیسے مختلف ہے؟

setNeedsDisplay() ویو کے مواد کی دوبارہ ڈرائنگ کی درخواست کرتا ہے (draw(_:) کال)۔ setNeedsLayout() ذیلی ویوز کی دوبارہ ترتیب کی درخواست کرتا ہے (layoutSubviews() کال)۔ layoutSubviews() سائز میں تبدیلی کا سبب بن سکتا ہے، جو بدلے میں دوبارہ ڈرائنگ کو متحرک کر سکتا ہے۔

setNeedsDisplay(_:) کب استعمال کرنا چاہیے؟

setNeedsDisplay(_:) نکاتی تبدیلیوں کے لیے استعمال کیا جانا چاہیے: کرسر کی حرکت، منتخب علاقے کا رنگ تبدیل کرنا، گراف کے حصے کو اپ ڈیٹ کرنا۔ یہ دوبارہ ڈرائنگ کے علاقے کو محدود کرتا ہے اور پورے ویو کو دوبارہ ڈرا کرنے کے مقابلے میں کارکردگی کو بہتر بناتا ہے۔

کیا frame تبدیل کرنا خود بخود setNeedsDisplay() کال کرتا ہے؟

پہلے سے طے شدہ طور پر، frame یا bounds تبدیل کرنا setNeedsDisplay() کال نہیں کرتا۔ سسٹم صرف ویو کو منتقل کرتا ہے۔ اگر سائز تبدیل کرنے پر دوبارہ ڈرائنگ کی ضرورت ہو تو، contentMode پراپرٹی کو .redraw پر سیٹ کریں — پھر UIKit خود بخود bounds کی ہر تبدیلی پر setNeedsDisplay() کال کرے گا۔

خلاصہ

  • setNeedsDisplay() — dirty فلیگ سیٹ کر کے التوا شدہ دوبارہ ڈرائنگ کی درخواست کرنے کے لیے UIView کا ایک غیر ہم وقت طریقہ
  • setNeedsDisplay(_:) — صرف مخصوص علاقے کی جزوی دوبارہ ڈرائنگ کے لیے CGRect کے ساتھ ایک اوورلوڈ، کارکردگی کو بہتر بناتا ہے
  • displayIfNeeded() — dirty ویوز کی فوری دوبارہ ڈرائنگ کے لیے ایک ہم وقت طریقہ، صرف جب بالکل ضروری ہو استعمال کیا جاتا ہے
  • Run loop — سسٹم موجودہ سائیکل کے آخر میں dirty ویوز کو پروسیس کرتا ہے، متعدد کالوں کو ایک draw(_:) پاس میں یکجا کرتا ہے
  • CALayer — اینیمیٹیبل پراپرٹیز (position, opacity) کے لیے draw(_:) کے بجائے Core Animation استعمال کریں — یہ کہیں زیادہ موثر ہے
  • CATransaction — متعدد تبدیلیوں کو ایک رینڈرنگ سائیکل میں گروپ کرتا ہے، draw(_:) کالوں کی تعداد کم کرتا ہے
  • contentMode = .redraw — ویو کے bounds تبدیل ہونے پر خودکار setNeedsDisplay() کال کو فعال کرتا ہے

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

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

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

مزید پڑھیں