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-এর একটি ইন্সট্যান্স মেথড যা 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(_:) এর আইডেম্পোটেন্সি নিয়ম

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(_:) সরাসরি কল নিষিদ্ধ
  • আইডেম্পোটেন্সি — সঠিক ক্যাশিংয়ের জন্য draw(_:) একই ইনপুট ডেটা সহ একই ফলাফল দিতে হবে
  • UIBezierPath — প্রতিটি কলের সময় CPU লোড কমাতে draw(_:) এর বাইরে পাথ তৈরি করুন
  • rect প্যারামিটার — পুনরায় আঁকার এলাকা ধারণ করে; অপ্টিমাইজেশনের জন্য ইন্টারসেকশন ব্যবহার করুন — এর বাইরে আঁকবেন না
  • প্রোফাইলিং — ধীরগতির অপারেশন চিহ্নিত করতে Instruments Core Animation এর মাধ্যমে draw(_:) পারফরম্যান্স পরীক্ষা করুন

আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব

IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।

প্রকল্প নিয়ে আলোচনা করুন

আরও পড়ুন