Custom UIView হল UIKit কম্পোনেন্ট UIView-এর একটি সাবক্লাস, যেখানে ডেভেলপার অনন্য ভিজুয়াল এলিমেন্ট তৈরি করার জন্য লাইফসাইকেল এবং ড্রয়িং মেথড ওভাররাইড করে। স্ট্যান্ডার্ড UIView (UIButton, UILabel, UIImageView) বেশিরভাগ সাধারণ পরিস্থিতি কভার করে, কিন্তু যখন অ-মানক গ্রাফিক্স, অ্যানিমেশন বা ইন্টারঅ্যাকটিভিটির প্রয়োজন হয়, তখন কাস্টম UIView তৈরি করা অপরিহার্য। Apple Documentation (2025) অনুসারে, App Store অ্যাপ্লিকেশনগুলির 68% ক্ষেত্রে কাস্টম 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 অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন