Custom UIView UIKit घटक UIView की एक उपक्लास है, जिसमें डेवलपर अद्वितीय दृश्य तत्व बनाने के लिए जीवनचक्र और ड्राइंग विधियों को ओवरराइड करता है। मानक UIView (UIButton, UILabel, UIImageView) अधिकांश सामान्य परिदृश्यों को कवर करते हैं, लेकिन जब गैर-मानक ग्राफिक्स, एनिमेशन या इंटरैक्टिविटी की आवश्यकता होती है, तो कस्टम UIView बनाना आवश्यक है। Apple Documentation (2025) के अनुसार, 68% App Store अनुप्रयोगों में कस्टम UIView का उपयोग किया जाता है जहाँ गैर-मानक इंटरफ़ेस समाधान होते हैं। यह दृष्टिकोण ड्राइंग, टच हैंडलिंग और व्यू के अंदर तत्वों की व्यवस्था पर पूर्ण नियंत्रण देता है।
मुख्य बिंदु
Custom UIView एक उपयोगकर्ता-परिभाषित वर्ग है जो UIView से विरासत प्राप्त करता है, जिसमें डेवलपर कस्टम डिस्प्ले और इंटरैक्शन लॉजिक को लागू करने के लिए मानक विधियों को ओवरराइड करता है। UIKit में कई अंतर्निहित घटक शामिल हैं, लेकिन वे सभी परिदृश्यों को कवर नहीं करते: एनिमेटेड चार्ट, कस्टम स्विच, फ्रीहैंड ड्राइंग कैनवास, गेम तत्व या डेटा विज़ुअलाइज़ेशन के लिए कस्टम कार्यान्वयन की आवश्यकता होती है।
Apple कस्टम UIView बनाने की सिफारिश करता है जब मानक घटक आवश्यक कार्यक्षमता प्रदान नहीं कर सकते या जब एक ही कस्टम तत्व का उपयोग एप्लिकेशन में कई स्थानों पर किया जाता है। WWDC 2024 के अनुसार, मध्यम आकार के प्रोजेक्ट में कस्टम व्यू सभी UIView का औसतन 15-20% बनाते हैं।
कस्टम UIView का उपयोग चार्ट और आरेख बनाने (Core Graphics के साथ रेखाएँ और आकृतियाँ बनाना), कस्टम प्रोग्रेस इंडिकेटर, एनिमेटेड बैकग्राउंड, फिंगर ड्राइंग तत्व और रीयल-टाइम डेटा विज़ुअलाइज़ेशन के लिए किया जाता है। इनमें से प्रत्येक मामले में, डेवलपर को CGContext तक पूर्ण पहुँच मिलती है और वह कोई भी ज्यामिति बना सकता है।
यदि किसी तत्व को मानक UIKit घटकों (UIButton, UIImageView, UILabel) से Auto Layout और प्रॉपर्टी कॉन्फ़िगरेशन का उपयोग करके इकट्ठा किया जा सकता है, तो UIView की उपक्लास बनाना अत्यधिक होगा। Apple पहले तैयार व्यू की संरचना का प्रयास करने और केवल कार्यक्षमता अपर्याप्त होने पर कस्टम ड्राइंग पर जाने की सिफारिश करता है।
कस्टम UIView बनाना UIView से विरासत प्राप्त करने वाले वर्ग की घोषणा और अनिवार्य इनिशियलाइज़र को लागू करने से शुरू होता है। न्यूनतम कार्यान्वयन में कोड से निर्माण के लिए init(frame:) और Storyboard या XIB से लोड करने के लिए init(coder:) शामिल है।
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() विधि में प्रारंभिक गुण सेट किए जाते हैं: पारदर्शी पृष्ठभूमि, परत सेटिंग्स। यदि व्यू Interface Builder में प्रदर्शित किया जाएगा, तो लाइव प्रीव्यू के लिए @IBDesignable और @IBInspectable जोड़ना उचित है।
Custom UIView सिस्टम द्वारा जीवनचक्र विधियों के अनुक्रम के माध्यम से प्रबंधित किया जाता है जो एक विशिष्ट क्रम में कॉल की जाती हैं। इस चक्र को समझना व्यू की सही सेटअप और ड्राइंग के लिए अत्यंत महत्वपूर्ण है।
| विधि | कब कॉल की जाती है | उद्देश्य |
|---|---|---|
| init(frame:) | कोड से व्यू बनाना | गुणों का आरंभीकरण, सबव्यू जोड़ना |
| init(coder:) | Storyboard/XIB से लोड करना | डिसीरियलाइज़ेशन और प्रारंभिक सेटअप |
| layoutSubviews() | फ्रेम बदलने पर | चाइल्ड तत्वों की ज्यामिति की पुनर्गणना |
| draw(_:) | पहली बार दिखने पर या setNeedsDisplay() के बाद | Core Graphics के माध्यम से सामग्री बनाना |
| didMoveToSuperview() | पदानुक्रम में जोड़े जाने के बाद | अंतिम सेटअप, एनिमेशन शुरू करना |
सभी विधियाँ सिस्टम द्वारा स्वचालित रूप से कॉल की जाती हैं, और डेवलपर को उन्हें मैन्युअल रूप से कॉल करने की आवश्यकता नहीं है। अपवाद setNeedsDisplay() है, जो सिस्टम को draw(_:) को फिर से कॉल करने का संकेत देता है।
draw(_:) Custom UIView में कस्टम ड्राइंग के लिए मुख्य विधि है। इसके अंदर, डेवलपर CGContext (ग्राफिक्स संदर्भ) तक पहुँच प्राप्त करता है और Core Graphics का उपयोग करके रेखाएँ, आकृतियाँ, पाठ और चित्र बना सकता है।
सिस्टम स्वचालित रूप से draw(_:) को कॉल करता है जब व्यू पहली बार स्क्रीन पर दिखाई देता है। बाद की कॉल setNeedsDisplay() के माध्यम से शुरू की जाती है, जो व्यू को पुनः ड्राइंग की आवश्यकता के रूप में चिह्नित करता है। महत्वपूर्ण: draw(_:) को सीधे कॉल न करें — यह कैशिंग तंत्र को तोड़ता है और प्रदर्शन को कम करता है।
override func draw(_ rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext() else { return }
// पृष्ठभूमि भरना
context.setFillColor(UIColor.systemBlue.cgColor)
context.fill(rect)
// एक वृत्त बनाना
context.setStrokeColor(UIColor.white.cgColor)
context.setLineWidth(4.0)
let circleRect = rect.insetBy(dx: 20, dy: 20)
context.strokeEllipse(in: circleRect)
}
इस उदाहरण में, draw(_:) पृष्ठभूमि को नीले रंग से भरता है और किनारों से 20 पिक्सेल के अंतर के साथ एक सफेद वृत्त बनाता है। draw(_:) की प्रत्येक कॉल समान-परिणामी होनी चाहिए — समान मापदंडों के साथ कई कॉल समान परिणाम देनी चाहिए।
Apple draw(_:) के अंदर काम कम करने की सिफारिश करता है — UIBezierPath पहले से बनाएं, छवियों को कैश करें और भारी गणना न करें। यदि व्यू स्थिर है, तो लगातार पुनः ड्राइंग के बजाय रेंडर की गई छवि के साथ UIImageView का उपयोग करने पर विचार करें।
CALayer अंतर्निहित परत है जो UIView की दृश्य सामग्री का प्रबंधन करती है। कस्टम ड्राइंग के कई कार्यों को draw(_:) को ओवरराइड किए बिना CALayer गुणों को कॉन्फ़िगर करके हल किया जा सकता है, जो काफी अधिक कुशल है।
Apple Engineering (2024) के अनुसार, CALayer स्तर पर संचालन GPU पर चलते हैं, जबकि draw(_:) CPU-आधारित Core Graphics रेंडरिंग के माध्यम से काम करता है। एनिमेशन और स्मूथ ट्रांज़िशन के लिए, CALayer और CABasicAnimation का उपयोग करना बेहतर है।
| परिदृश्य | अनुशंसित दृष्टिकोण | प्रदर्शन |
|---|---|---|
| गोल कोने | layer.cornerRadius | GPU, उच्च |
| छायाएँ और ग्रेडिएंट | CAGradientLayer, shadowPath | GPU, उच्च |
| मनमानी आकृतियाँ | UIBezierPath के साथ CAShapeLayer | GPU, उच्च |
| जटिल ग्राफिक्स | Core Graphics के साथ draw(_:) | CPU, मध्यम |
| कस्टम फ़ॉर्मेटिंग वाला पाठ | CATextLayer या draw(_:) | मात्रा पर निर्भर करता है |
एनिमेशन के साथ वेक्टर आकृतियाँ बनाने के लिए CAShapeLayer का उपयोग करें — यह हार्डवेयर त्वरित है और draw(_:) को कॉल किए बिना path, strokeStart और strokeEnd एनिमेशन का समर्थन करता है।
Custom UIView का प्रदर्शन सीधे एनिमेशन की सहजता और समग्र उपयोगकर्ता अनुभव को प्रभावित करता है। मुख्य समस्याएँ draw(_:) के अत्यधिक कॉल, सबव्यू के असंगत लेआउट और कैशिंग की कमी से उत्पन्न होती हैं।
setNeedsDisplay() की प्रत्येक कॉल व्यू की पूर्ण पुनः ड्राइंग को ट्रिगर करती है। यदि परिवर्तन केवल व्यू के भाग को प्रभावित करते हैं, तो एक विशिष्ट आयत के साथ setNeedsDisplay(_:) का उपयोग करें। CALayer गुणों (backgroundColor, cornerRadius, shadow) के लिए पुनः ड्राइंग की आवश्यकता नहीं है — वे GPU स्तर पर अपडेट होते हैं।
यदि Custom UIView की सामग्री शायद ही कभी बदलती है, तो इसे UIGraphicsImageRenderer में एक बार रेंडर करें और UIImage के रूप में सहेजें। अगली पुनः ड्राइंग पर, कैश की गई छवि प्रदर्शित करने के लिए draw(at:) का उपयोग करें — यह Core Graphics के माध्यम से पुनः रेंडर करने की तुलना में दस गुना तेज़ है।
func renderToImage() -> UIImage {
let renderer = UIGraphicsImageRenderer(size: bounds.size)
return renderer.image { ctx in
drawHierarchy(in: bounds, afterScreenUpdates: true)
}
}
CALayer पर shouldRasterize गुण परत के बिटमैप प्रतिनिधित्व की कैशिंग सक्षम करता है। पारदर्शिता और छाया वाले स्थिर व्यू के लिए इसे चालू करें — इससे कम्पोज़िटिंग लोड कम होता है। एनिमेटेड व्यू के लिए इसे बंद करें: प्रत्येक परिवर्तन पर कैश रीसेट हो जाता है, और रैस्टराइज़ेशन केवल प्रदर्शन को ख़राब करता है।
अक्सर पूछे जाने वाले प्रश्न
नहीं, draw(_:) केवल Core Graphics के माध्यम से कस्टम ड्राइंग के लिए आवश्यक है। यदि व्यू मानक सबव्यू (UILabel, UIImageView) से बना है और CALayer का उपयोग करता है, तो draw(_:) को ओवरराइड करना आवश्यक नहीं है — इससे प्रदर्शन में भी सुधार होगा।
कैनवास पर एक सामान्य UIView रखें, Identity Inspector में Class फ़ील्ड में अपना वर्ग निर्दिष्ट करें। यदि वर्ग @IBDesignable से चिह्नित है, तो परिवर्तन Storyboard में वास्तविक समय में प्रदर्शित होंगे।
init(frame:) प्रोग्रामेटिक रूप से व्यू बनाते समय कॉल किया जाता है — आप स्थिति और आकार के साथ CGRect पास करते हैं। init(coder:) Storyboard या XIB से डिसीरियलाइज़ करते समय कॉल किया जाता है। सही संचालन के लिए, दोनों को लागू किया जाना चाहिए, अन्यथा Interface Builder से लोड करने पर आपका व्यू क्रैश हो जाएगा।
सबसे सामान्य कारण यह है कि व्यू का शून्य फ्रेम है (चौड़ाई या ऊँचाई शून्य के बराबर है)। सिस्टम शून्य आयाम वाले व्यू के लिए draw(_:) को कॉल नहीं करता है। layoutSubviews() में फ्रेम की जाँच करें और सुनिश्चित करें कि व्यू सही बाधाओं के साथ पदानुक्रम में जोड़ा गया है।
GPU एनिमेशन (position, opacity, transform) का समर्थन करने वाले गुणों के लिए CALayer का उपयोग करें। draw(_:) के आंशिक अपडेट के लिए, परिवर्तित क्षेत्र के CGRect के साथ setNeedsDisplay(_:) का उपयोग करें — सिस्टम केवल निर्दिष्ट क्षेत्र को फिर से बनाएगा, पूरे व्यू को नहीं।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें