View Protocol হল SwiftUI-এর মৌলিক প্রোটোকল যা যেকোনো ভিজ্যুয়াল ইন্টারফেস কম্পোনেন্টকে মেনে চলতে হবে। Apple Developer Documentation, 2024 অনুসারে, View একটি একক চুক্তি সংজ্ঞায়িত করে: যে স্ট্রাকচার বা ক্লাস এই প্রোটোকল বাস্তবায়ন করে তাকে অবশ্যই একটি কম্পিউটেড প্রপার্টি body প্রদান করতে হবে। এই প্রোটোকলের মাধ্যমে, SwiftUI সাধারণ টেক্সট লেবেল থেকে জটিল নেভিগেশন স্ট্রাকচার পর্যন্ত সম্পূর্ণ স্ক্রিন হায়ারার্কি তৈরি করে।
মূল পয়েন্ট
View Protocol হল SwiftUI-এর কেন্দ্রীয় প্রোটোকল যা সংজ্ঞায়িত করে যে কীভাবে যেকোনো ভিজ্যুয়াল এলিমেন্ট তার কন্টেন্ট বর্ণনা করে। UIKit-এর বিপরীতে, যেখানে প্রতিটি এলিমেন্ট ক্লাসের মাধ্যমে UIView থেকে ইনহেরিট করে, SwiftUI প্রোটোকল-ওরিয়েন্টেড পদ্ধতি ব্যবহার করে: যেকোনো টাইপ যা View প্রোটোকল মেনে চলে তা স্ক্রিনে প্রদর্শিত হতে পারে।
View প্রোটোকলের জন্য একটি একক কম্পিউটেড প্রপার্টি body বাস্তবায়ন প্রয়োজন যা কিছু কন্টেন্ট রিটার্ন করে। তবে, এই সরলতার পিছনে একটি শক্তিশালী কম্পোজিশন সিস্টেম লুকিয়ে আছে: body যেকোনো টাইপ রিটার্ন করতে পারে যা View মেনে চলে, যার মধ্যে প্রিমিটিভ (Text, Image, Button), কন্টেইনার (VStack, HStack, ZStack) এবং কাস্টম কম্পোজিট কম্পোনেন্ট অন্তর্ভুক্ত।
WWDC 2023 অনুসারে, SwiftUI অ্যাপ্লিকেশনগুলিতে 95% এরও বেশি স্ক্রিন View প্রোটোকল বাস্তবায়নকারী স্ট্রাকচারগুলির কম্পোজিশনের মাধ্যমে তৈরি করা হয়। এটি View Protocol-কে সম্পূর্ণ SwiftUI আর্কিটেকচারের ভিত্তি করে তোলে।
SwiftUI-তে View-কে ভ্যালু টাইপ (value type) (struct) হতে হবে, ক্লাস নয়। এটি একটি মূল আর্কিটেকচারাল সিদ্ধান্ত: ভ্যালু টাইপগুলির একটি পূর্বাভাসযোগ্য জীবনকাল থাকে, কোনও ভাগ করা পরিবর্তনীয় অবস্থা থাকে না এবং SwiftUI-কে দক্ষতার সাথে নির্ধারণ করতে দেয় যে হায়ারার্কির কোন অংশগুলি পরিবর্তিত হয়েছে এবং পুনরায় আঁকার প্রয়োজন।
আপনি যদি View-কে একটি ক্লাস বানানোর চেষ্টা করেন, কম্পাইলার একটি ত্রুটি দেখাবে: View প্রোটোকল DynamicViewProperty প্রোটোকল থেকে ইনহেরিট করে, যার জন্য ভ্যালু সিম্যান্টিক্স প্রয়োজন। ক্লাসগুলি View মেনে চলতে পারে, কিন্তু এটি ইডিওম্যাটিক পদ্ধতি ভঙ্গ করে এবং স্বয়ংক্রিয় আপডেটের সুবিধাগুলি হারায়।
body হল View প্রোটোকলের একমাত্র বাধ্যতামূলক প্রয়োজনীয়তা। এটি একটি কম্পিউটেড প্রপার্টি যা স্ক্রিনে প্রদর্শিত কন্টেন্ট রিটার্ন করে। রিটার্ন টাইপ হল some View, যার অর্থ “একটি টাইপ যা View মেনে চলে, যা কম্পাইলার দ্বারা নির্ধারিত হবে”।
struct GreetingView: View {
var name: String
var body: some View {
VStack {
Text("Hello, \(name)!")
.font(.title)
.foregroundColor(.blue)
Button("Start") {
print("Button pressed")
}
}
}
}
body কিভাবে কাজ করে: SwiftUI body-কে প্রতিবার কল করে যখন অ্যাপ্লিকেশনের অবস্থা পরিবর্তিত হয় এবং পুনরায় আঁকার প্রয়োজন হয়। ফ্রেমওয়ার্ক নতুন View ট্রিকে পুরানোটির সাথে তুলনা করে এবং শুধুমাত্র প্রয়োজনীয় পরিবর্তনগুলি প্রয়োগ করে (diffing)। এটি সম্পূর্ণ ঘোষণামূলক পদ্ধতি — আপনি বর্ণনা করেন কী প্রদর্শিত হওয়া উচিত, এবং SwiftUI এটি কীভাবে বাস্তবায়ন করতে হবে তা দেখাশোনা করে।
একটি গুরুত্বপূর্ণ বিবরণ: body-তে পার্শ্ব প্রতিক্রিয়া থাকা উচিত নয়। এটি অ্যাপ্লিকেশনের জীবনকালে বহুবার কল করা হয়, এবং যদি body বাহ্যিক অবস্থা পরিবর্তন করে — তবে এটি অপ্রত্যাশিত আচরণের দিকে নিয়ে যায়। পার্শ্ব প্রতিক্রিয়ার জন্য, task, onChange বা DispatchQueue ব্যবহার করুন।
SwiftUI একটি বাধা আরোপ করে: body শুধুমাত্র একটি রুট এলিমেন্ট রিটার্ন করতে পারে। যদি আপনাকে একই স্তরে একাধিক এলিমেন্ট প্রদর্শন করতে হয়, তবে সেগুলিকে একটি কন্টেইনারে মোড়ান — VStack, HStack, ZStack বা Group। @ViewBuilder-এর আগমনের সাথে, এই সীমা কম লক্ষণীয় হয়ে উঠেছে, কিন্তু ধারণাগতভাবে body সর্বদা একটি একক View রিটার্ন করে।
some View হল অপ্রকাশ্য টাইপ (opaque type) সিনট্যাক্স যা Swift 5.1-এ বিশেষত SwiftUI-র জন্য প্রবর্তিত হয়েছিল। এর অর্থ হল একটি ফাংশন বা প্রপার্টি একটি কংক্রিট টাইপ রিটার্ন করে যা View প্রোটোকল মেনে চলে, কিন্তু কলিং কোড জানে না এবং জানার প্রয়োজনও নেই যে কোন সঠিক টাইপ রিটার্ন করা হয়েছে।
Swift কম্পাইলার প্রতিটি body বাস্তবায়নের জন্য কম্পাইল সময়ে কংক্রিট টাইপ নির্ধারণ করে, কিন্তু এটি বাইরের বিশ্ব থেকে লুকিয়ে রাখে। এটি SwiftUI-কে সমস্ত কম্পোনেন্টের সঠিক টাইপ জানার মাধ্যমে View হায়ারার্কি অপ্টিমাইজ করতে দেয়, পাশাপাশি ডেভেলপারকে সিগনেচার পরিবর্তন না করেই বাস্তবায়ন পরিবর্তনের নমনীয়তা দেয়।
struct ContentView: View {
var body: some View {
Text("Hello, World!") // Compiler knows this is Text
}
}
কেন some View এবং শুধু View নয়? যদি body শুধু View (একটি প্রোটোকল হিসাবে) রিটার্ন করত, তাহলে SwiftUI কম্পাইল সময়ে কংক্রিট টাইপ নির্ধারণ করতে পারত না। এটি একটি একজিস্টেনশিয়াল কন্টেইনারে মোড়ানোর অতিরিক্ত ব্যয় যুক্ত করত। some View কম্পাইলারকে প্রোটোকলের নমনীয়তা বজায় রেখে অপ্টিমাইজেশনের জন্য যথেষ্ট তথ্য দেয়।
মূল সীমাবদ্ধতা হল body-কে একই টাইপ রিটার্ন করতে হবে। আপনি একটি শর্তের এক শাখায় Text এবং অন্য শাখায় Image বিশেষ র্যাপার (AnyView, Group, বা @ViewBuilder) ছাড়া রিটার্ন করতে পারবেন না। কম্পাইলার কম্পাইল সময়ে এটি পরীক্ষা করে: সমস্ত সম্ভাব্য রিটার্ন পাথের একই টাইপ থাকতে হবে।
এই সীমাবদ্ধতা এড়াতে @ViewBuilder (একক TupleView টাইপ তৈরি করে), Group (যাও একটি একক টাইপ রিটার্ন করে) বা AnyView (টাইপ মুছে দেয় কিন্তু অতিরিক্ত ব্যয় যোগ করে) ব্যবহার করা হয়। AnyView শুধুমাত্র তখন ব্যবহার করা উচিত যখন অন্যান্য বিকল্পগুলি সম্ভব না হয়, কারণ এটি SwiftUI অপ্টিমাইজেশন নিষ্ক্রিয় করে।
@ViewBuilder হল একটি রিজাল্ট বিল্ডার যার অ্যানোটেশন নেস্টেড কন্টেইনার ছাড়াই একাধিক Views-কে একটি কম্পোজিশনে একত্রিত করতে দেয়। @ViewBuilder স্বয়ংক্রিয়ভাবে একাধিক এক্সপ্রেশনকে একটি টাপলে (TupleView) মোড়ায় বা সঠিক রিটার্ন টাইপ সহ শর্তসাপেক্ষ লজিক (If / else / switch) প্রয়োগ করে।
struct DashboardView: View {
var isLoggedIn: Bool
@ViewBuilder
var body: some View {
if isLoggedIn {
Text("Welcome!")
.font(.largeTitle)
ProfileCard()
} else {
LoginButton()
.padding()
}
}
}
@ViewBuilder কিভাবে কাজ করে: কম্পাইলার @ViewBuilder-এর ভিতরে কোডের প্রতিটি ব্লককে স্ট্যাটিক মেথড buildBlock, buildEither, buildOptional ইত্যাদির কলিতে রূপান্তর করে। যদি একটি ব্লকে একাধিক এক্সপ্রেশন থাকে — তবে সেগুলি TupleView-এ মোড়ানো হয়। যদি একটি ব্লকে শর্তসাপেক্ষ লজিক থাকে — তবে কম্পাইলার ConditionalContent তৈরি করে, শাখার টাইপ লুকিয়ে।
@ViewBuilder একটি সীমা আরোপ করে: একটি ব্লকে সর্বোচ্চ 10 টি এলিমেন্ট (TupleView সীমা)। যদি দশের বেশি এলিমেন্ট একত্রিত করতে হয়, তাহলে Group, ForEach ব্যবহার করুন বা উপ-কম্পোনেন্টে ভাগ করুন। এই সীমা বিদ্যমান কারণ Swift প্রতিটি আরিটি 1 থেকে 10-এর জন্য একটি পৃথক buildBlock ওভারলোড তৈরি করে।
কম্পোজিশন (Composition) হল SwiftUI-এর একটি মূল নীতি: জটিল ইন্টারফেসগুলি ছোট, পুনর্ব্যবহারযোগ্য View কম্পোনেন্ট থেকে তৈরি করা হয়। প্রতিটি কম্পোনেন্ট View প্রোটোকল বাস্তবায়ন করে এবং স্ক্রিনের নিজস্ব অংশের জন্য দায়ী। মডিফায়ার (font, padding, foregroundColor) View-তে প্রয়োগ করা হয় এবং পরিবর্তিত সেটিংস সহ একটি নতুন View রিটার্ন করে।
SwiftUI-তে মডিফায়ারগুলি মিউটেশন নয়, বরং মূল View-এর চারপাশে একটি নতুন র্যাপার তৈরি করা। প্রতিটি মডিফায়ার একটি নতুন টাইপ (ModifiedContent) রিটার্ন করে, যা SwiftUI-কে একটি মডিফায়ার ট্রি তৈরি করতে এবং শুধুমাত্র পরিবর্তিত অংশগুলি দক্ষতার সাথে পুনরায় আঁকতে দেয়। মডিফায়ার প্রয়োগের ক্রম গুরুত্বপূর্ণ: বিভিন্ন ক্রম বিভিন্ন ভিজ্যুয়াল ফলাফল দেয়।
Text("Hello, SwiftUI!")
.font(.title) // ModifiedContent
.padding() // ModifiedContent<..., PaddingModifier>
.background(.yellow) // ModifiedContent<..., BackgroundModifier>
.cornerRadius(8) // ModifiedContent<..., CornerRadiusModifier>
পারফরম্যান্স অপ্টিমাইজেশন: SwiftUI View-এর কংক্রিট মান তুলনা করে না, বরং আইডেন্টিটি মেকানিজম (id, ForEach, স্ট্রাকচারের স্থিতিশীল আইডেন্টিটি) এর মাধ্যমে তাদের আইডেন্টিটি তুলনা করে। যদি View-এর স্ট্রাকচার পরিবর্তিত না হয় — তবে body কল করা হয় না। এটি Equatable তুলনা এবং হায়ারার্কিতে ডেটা উপরে পাঠানোর জন্য PreferenceKey মেকানিজমের মাধ্যমে অর্জন করা হয়।
কার্যকর কম্পোজিশনের জন্য, জটিল স্ক্রিনগুলিকে স্বাধীন উপ-কম্পোনেন্টে বিভক্ত করার পরামর্শ দেওয়া হয়, প্রতিটি তার নিজস্ব ন্যূনতম অবস্থা সহ। এটি SwiftUI-কে সম্পূর্ণ স্ক্রিনের পরিবর্তে হায়ারার্কির শুধুমাত্র পরিবর্তিত অংশগুলি পুনরায় আঁকতে দেয়।
সচরাচর জিজ্ঞাসা
View Protocol হল SwiftUI-এর বেস প্রোটোকল যা যেকোনো প্রদর্শিত কম্পোনেন্টকে মেনে চলতে হবে। এটি একটি একক কম্পিউটেড body প্রপার্টি প্রয়োজন যা কন্টেন্ট রিটার্ন করে। সমস্ত স্ট্যান্ডার্ড SwiftUI এলিমেন্ট — Text, Button, Image, VStack — এই প্রোটোকল বাস্তবায়ন করে।
SwiftUI পূর্বাভাসযোগ্য ইন্টারফেস আপডেটের জন্য ভ্যালু সিম্যান্টিক্স (value semantics) ব্যবহার করে। স্ট্রাকচারগুলির কোনও ভাগ করা পরিবর্তনীয় অবস্থা নেই, যা SwiftUI-কে পুরানো এবং নতুন View হায়ারার্কি দক্ষতার সাথে তুলনা করতে এবং শুধুমাত্র পরিবর্তিত এলিমেন্টগুলি পুনরায় আঁকতে দেয়। ক্লাসগুলি এই অপ্টিমাইজেশন ভঙ্গ করে।
body some View রিটার্ন করে — একটি অপ্রকাশ্য টাইপ যা কংক্রিট বাস্তবায়ন লুকায়। এটি আসলে যেকোনো টাইপ রিটার্ন করে যা View মেনে চলে: Text, Image, VStack, কাস্টম স্ট্রাকচার। কম্পাইলার অপ্টিমাইজেশনের জন্য কম্পাইল সময়ে কংক্রিট টাইপ নির্ধারণ করে।
some View হল কম্পাইল সময়ে কংক্রিট টাইপ নির্ধারণ সহ একটি অপ্রকাশ্য টাইপ। AnyView হল টাইপ ইরেজার (type erasure), যেকোনো View-কে একটি একক কন্টেইনারে মোড়ানো। some View বেশি কার্যকর; AnyView অতিরিক্ত ব্যয় যোগ করে এবং শুধুমাত্র যখন গতিশীল টাইপ স্যুইচিং প্রয়োজন তখন ব্যবহার করা হয়।
সর্বোচ্চ 10 টি এলিমেন্ট — এটি TupleView সীমা, যা আরিটি 1 থেকে 10-এর জন্য buildBlock তৈরি করে। যদি আপনার আরও এলিমেন্টের প্রয়োজন হয়, তাহলে Group, ForEach, List ব্যবহার করুন বা উপ-কম্পোনেন্টে ভাগ করুন। এই সীমা Swift কম্পাইলার স্তরে বিদ্যমান।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন