@ViewBuilder SwiftUI میں ایک result builder کا اعلان ہے جو View کے درجہ بندی کی اعلانیہ تعمیر کے لیے ڈیزائن کیا گیا ہے۔ Apple Developer Documentation, 2024 کے مطابق، @ViewBuilder متعدد اظہارات اور مشروط منطق والے کوڈ کے بلاک کو Swift کمپائلر کے لیے قابل فہم ایک واحد View قسم میں تبدیل کرتا ہے۔ اس اعلان کے بغیر، if/else اور body میں متعدد عناصر کے ساتھ واقف اعلانیہ SwiftUI نحو کا استعمال ناممکن ہوگا۔
اہم نکات
@ViewBuilder ایک اعلان ہے جو result builder پیٹرن (SE-0289) کو نافذ کرتا ہے، جو SwiftUI کو اعلانیہ نحو کا استعمال کرتے ہوئے متعدد Views کو ایک ترکیب میں جمع کرنے کی اجازت دیتا ہے۔ یہ خود بخود متعدد اظہارات، مشروط تعمیرات اور اختیاری اقدار کو ان کی متعلقہ اقسام میں لپیٹتا ہے: TupleView، ConditionalContent، OptionalContent۔
result builders کے آنے سے پہلے، ڈویلپرز کو دستی طور پر عناصر کو VStack یا HStack میں لپیٹنا پڑتا تھا، اور مشروط منطق کے لیے تینوں آپریٹرز یا فیکٹری طریقے استعمال کرنے پڑتے تھے۔ @ViewBuilder نے SwiftUI کے نحو کو مختصر اور پڑھنے کے قابل بنا دیا، جس سے if/else اور لوپس کے ساتھ عام Swift جیسا کوڈ لکھنا ممکن ہوا۔
Swift Evolution SE-0289 کے مطابق، result builders ایک عام طریقہ کار ہے جو SwiftUI سے منسلک نہیں ہے۔ @ViewBuilder اس طریقہ کار کا ایک نفاذ ہے، ساتھ ہی @StringBuilder سٹرنگ کی تعمیر کے لیے اور دیگر DSLs کے لیے لائبریری کے نفاذ بھی ہیں۔ SwiftUI میں، @ViewBuilder نہ صرف body کے لیے بلکہ کنٹینرز (VStack، HStack، ZStack، List) کے closure پیرامیٹرز کے لیے بھی استعمال ہوتا ہے۔
امری UIKit میں، آپ واضح طور پر ایک UIView بناتے ہیں، اس کی خصوصیات کو ترتیب دیتے ہیں اور addSubview کے ذریعے اسے درجہ بندی میں شامل کرتے ہیں۔ @ViewBuilder کے ساتھ SwiftUI میں، آپ اعلانیہ طور پر بیان کرتے ہیں کہ کون سے Views دکھائے جانے چاہئیں، اور SwiftUI حالت میں تبدیلیوں کی بنیاد پر عناصر کی تخلیق، تازہ کاری اور ہٹانے کا انتظام کرتا ہے۔
Result builder Swift کا ایک طریقہ کار ہے جو جامد طریقوں buildBlock، buildOptional، buildEither اور دیگر کے ذریعے اظہارات کی ترتیب کو ایک واحد مرکب قدر میں تبدیل کرتا ہے۔ جب کمپائلر @ViewBuilder کا اعلان دیکھتا ہے، تو وہ تالیف کے دوران خود بخود ان طریقوں کو کوڈ بلاک پر لاگو کرتا ہے۔
@resultBuilder
struct ViewBuilder {
static func buildBlock<C0, C1>(_ c0: C0, _ c1: C1) -> TupleView<(C0, C1)>
static func buildIf<C>(_ c: C?) -> C?
static func buildEither<T, F>(first: T) -> ConditionalContent<T, F>
static func buildEither<T, F>(second: F) -> ConditionalContent<T, F>
}
buildBlock 1 سے 10 اظہارات قبول کرتا ہے اور TupleView واپس کرتا ہے۔ ہر arity (اظہارات کی تعداد) کا اپنا buildBlock اوورلوڈ ہے: buildBlock
buildEither (first/second) if/else تعمیرات کو سنبھالتا ہے۔ ہر شاخ متعلقہ طریقے کو بھیجی جاتی ہے، اور نتیجہ ConditionalContent میں لپیٹا جاتا ہے — ایک قسم جو مخصوص شاخوں کی اقسام کو چھپاتی ہے اور SwiftUI کے لیے ایک متحد انٹرفیس فراہم کرتی ہے۔
SwiftUI میں، body پراپرٹی پہلے سے @ViewBuilder کے ساتھ مخفی طور پر اعلان شدہ ہے — آپ کوڈ میں یہ اعلان نہیں دیکھتے، لیکن کمپائلر اسے خود بخود لاگو کرتا ہے۔ تاہم، حسب ضرورت پراپرٹیز کے لیے جو متعدد Views واپس کرتی ہیں، یا closure پیرامیٹرز کے لیے، اعلان کو واضح طور پر بتایا جانا چاہیے۔
حد 1 — ایک بلاک میں 10 عناصر۔ یہ @ViewBuilder کی سب سے معروف حد ہے۔ اگر آپ کو ایک ہی سطح پر 10 سے زیادہ عناصر دکھانے کی ضرورت ہے، تو کمپائلر ایک خرابی پیدا کرے گا۔ حل میں Group، ForEach، List یا ذیلی اجزاء میں تقسیم شامل ہے۔ Group بصری گھریلو پن کا اضافہ نہیں کرتا، لیکن ہر Group ایک عنصر کے طور پر شمار ہوتا ہے۔
struct ManyElementsView: View {
var body: some View {
Group {
Text("1"); Text("2"); Text("3")
Text("4"); Text("5"); Text("6")
Text("7"); Text("8"); Text("9")
}
Group {
Text("10"); Text("11"); Text("12")
}
}
}
حد 2 — بعض تعمیرات کے لیے معاونت کی کمی۔ @ViewBuilder do/catch، guard، for-in (ForEach کے بغیر) اور دیگر کنٹرول فلو تعمیرات کو سپورٹ نہیں کرتا۔ لوپس کے لیے، قابل شناخت ڈیٹا کے ساتھ ForEach استعمال کریں۔ خرابی سے نمٹنے کے لیے، علیحدہ Views استعمال کریں جو Result یا اختیاری اقدار قبول کریں۔
حد 3 — ڈیبگنگ کی پیچیدگی۔ @ViewBuilder میں خرابیاں ہونے پر، کمپائلر تفصیلی پیغامات تیار کرتا ہے جن میں بنیادی وجہ تلاش کرنا مشکل ہوتا ہے۔ عام مسائل: if/else شاخوں میں قسم کی عدم مطابقت، 10 عناصر کی حد سے تجاوز، یا buildBlock کے مطلوبہ اوورلوڈز کی عدم موجودگی۔
نمونہ 1: if/else کے ذریعے مشروط ڈسپلے۔ @ViewBuilder کا سب سے عام استعمال۔ یہ تینوں آپریٹرز یا فیکٹری طریقوں کے استعمال کے بغیر حالت کی بنیاد پر مختلف Views دکھانے کی اجازت دیتا ہے۔
struct StatusView: View {
var status: LoadStatus
@ViewBuilder
var body: some View {
switch status {
case .loading:
ProgressView("Loading...")
case .loaded(let data):
DataView(data: data)
case .error(let message):
ErrorView(message: message)
}
}
}
نمونہ 2: افعال اور ابتدائیہ پیرامیٹرز میں @ViewBuilder۔ یہ دوبارہ استعمال کے قابل کنٹینر بنانے کے لیے استعمال ہوتا ہے جو closure کے ذریعے چائلڈ Views قبول کرتے ہیں۔ یہ لائبریریوں اور UI اجزاء کے لیے معیاری نمونہ ہے۔
struct SectionCard<Content: View>: View {
let title: String
@ViewBuilder let content: Content
var body: some View {
VStack(alignment: .leading) {
Text(title).font(.headline)
content
}
.padding()
.background(Color.gray.opacity(0.1))
.cornerRadius(12)
}
}
نمونہ 3: ForEach کے ساتھ ترکیب۔ @ViewBuilder ForEach کے ساتھ صحیح طریقے سے کام کرتا ہے، جو ڈیٹا کی صف سے عناصر کی متحرک تخلیق کی اجازت دیتا ہے۔ ForEach کا ہر عنصر @ViewBuilder کے سیاق و سباق میں ایک اظہار کے طور پر شمار ہوتا ہے۔
حسب ضرورت ViewBuilder ایک صارف کی طرف سے متعین کردہ فنکشن یا پراپرٹی ہے جو @ViewBuilder کے ساتھ اعلان شدہ ہے اور some View واپس کرتی ہے۔ اس طرح کے افعال پیچیدہ ڈسپلے منطق کو سمیٹنے اور ایپلیکیشن کے مختلف حصوں میں دوبارہ استعمال کرنے کی اجازت دیتے ہیں۔
struct FormRow<Content: View>: View {
let label: String
@ViewBuilder let content: Content
var body: some View {
HStack {
Text(label)
.frame(width: 120, alignment: .trailing)
content
}
}
}
// استعمال:
FormRow(label: "Name") {
TextField("Enter name", text: $name)
}
FormRow(label: "Gender") {
Picker("Select", selection: $gender) {
Text("مرد").tag(Gender.male)
Text("عورت").tag(Gender.female)
}
}
اہم اصول: @ViewBuilder کے ساتھ ایک حسب ضرورت فنکشن کو some View واپس کرنا چاہیے، نہ کہ کوئی ٹھوس قسم یا View پروٹوکول۔ صرف مبہم قسم ترکیب کی لچک کو برقرار رکھتے ہوئے ٹھوس نفاذ کو چھپانے کی اجازت دیتی ہے۔
کارکردگی: حسب ضرورت @ViewBuilder افعال براہ راست body کوڈ کے مقابلے میں کوئی اضافی بوجھ نہیں ڈالتے۔ کمپائلر کالز کو ان لائن کرتا ہے اور نتیجے میں آنے والے کوڈ کو بہتر بناتا ہے۔ body کو @ViewBuilder افعال میں تقسیم کرنا کارکردگی کی قربانی کے بغیر پڑھنے کی اہلیت کو بہتر بناتا ہے۔
اکثر پوچھے گئے سوالات
@ViewBuilder ایک result builder کا اعلان ہے جو متعدد اظہارات اور شرائط والے کوڈ بلاک کو ایک واحد View قسم میں تبدیل کرتا ہے۔ یہ SwiftUI کے اعلانیہ UI کے اندر واقف Swift نحو (if/else، switch، اختیاری اظہارات) استعمال کرنے کی اجازت دیتا ہے۔
حد buildBlock کے نفاذ کی وجہ سے ہے — 1 سے 10 تک ہر arity کے لیے طریقہ کار کا ایک علیحدہ اوورلوڈ موجود ہے۔ Swift متغیر جنریکس کو سپورٹ نہیں کرتا، اس لیے اوورلوڈز کی تعداد مقرر ہے۔ اس سے بچنے کے لیے، Group، ForEach یا ذیلی اجزاء استعمال کریں۔
نہیں، View پروٹوکول body پراپرٹی پر @ViewBuilder کو مخفی طور پر لاگو کرتا ہے۔ تاہم، حسب ضرورت پراپرٹیز، طریقوں اور closure پیرامیٹرز کے لیے جو متعدد Views واپس کرتے ہیں، اعلان کو واضح طور پر بتایا جانا چاہیے۔ اس کے بغیر، کمپائلر متعدد اظہارات کو سنبھالنے کے قابل نہیں ہوگا۔
اختیاری اظہارات کے لیے، buildIf طریقہ استعمال کیا جاتا ہے، جو ایک اختیاری View قبول کرتا ہے اور اگر کوئی قدر موجود ہو تو اسے واپس کرتا ہے۔ اگر قدر nil ہے، تو buildIf nil واپس کرتا ہے اور عنصر ظاہر نہیں ہوتا۔ یہ body کے اندر if let استعمال کرنے کی اجازت دیتا ہے۔
ہاں، Swift 5.9 سے @ViewBuilder buildExpression طریقہ کے ذریعے switch کو سپورٹ کرتا ہے۔ کمپائلر ہر case شاخ کو متعلقہ buildEither کال میں تبدیل کرتا ہے۔ switch کی معاونت nested if/else تعمیرات کے مقابلے کوڈ کو مزید پڑھنے کے قابل بناتی ہے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں