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 एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।

परियोजना पर चर्चा करें

यह भी पढ़ें