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 مرتب وقت پر ٹھوس قسم کا تعین نہیں کر سکتا تھا۔ یہ وجودی کنٹینر (existential container) میں لپیٹنے کا اضافی بوجھ ڈالتا۔ some View کمپائلر کو پروٹوکول کی لچک برقرار رکھتے ہوئے اصلاح کے لیے کافی معلومات دیتا ہے۔
بنیادی حد یہ ہے کہ body کو ایک ہی قسم لوٹانی چاہیے۔ آپ خصوصی ریپر (AnyView, Group یا @ViewBuilder) کے بغیر کسی شرط کی ایک شاخ میں Text اور دوسری میں Image نہیں لوٹا سکتے۔ کمپائلر مرتب وقت پر اسے چیک کرتا ہے: تمام ممکنہ واپسی کے راستوں کی ایک ہی قسم ہونی چاہیے۔
اس حد کو دور کرنے کے لیے @ViewBuilder (ایک واحد TupleView قسم بناتا ہے)، Group (جو بھی ایک قسم لوٹاتا ہے) یا AnyView (قسم مٹاتا ہے لیکن اضافی بوجھ ڈالتا ہے) استعمال کیا جاتا ہے۔ AnyView صرف اس وقت استعمال کرنا چاہیے جب دوسرے اختیارات ممکن نہ ہوں، کیونکہ یہ SwiftUI کی اصلاحات کو غیر فعال کرتا ہے۔
@ViewBuilder ایک result builder ہے جس کا حاشیہ اندرونی کنٹینرز کے بغیر کئی 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 ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں