draw(_:) / drawRect হলো UIView ক্লাসের (Swift-এ) একটি মেথড এবং Objective-C-তে এর সমতুল্য (drawRect:), যা Core Graphics ব্যবহার করে ভিউয়ের কন্টেন্ট রেন্ডার করার জন্য দায়ী। সিস্টেম স্বয়ংক্রিয়ভাবে এই মেথডটি কল করে যখন ভিউ প্রথমবার স্ক্রিনে দেখা যায় এবং setNeedsDisplay() কল করার পরে। Apple Documentation (2025) অনুসারে, draw(_:) হলো একমাত্র মেথড যেখানে ডেভেলপার কাস্টম ড্রইংয়ের জন্য বর্তমান স্ক্রিনের গ্রাফিক্স কন্টেক্সট অ্যাক্সেস করতে পারেন। draw(_:) ওভাররাইড করা কম্পোনেন্টের চেহারার উপর সম্পূর্ণ নিয়ন্ত্রণ দেয় — সাধারণ জ্যামিতিক আকার থেকে জটিল অ্যানিমেটেড গ্রাফিক্স পর্যন্ত।
মূল বিষয়
draw(_:) হলো UIView-এর একটি ইন্সট্যান্স মেথড যা 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 অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন