कस्टम दृश्य संशोधक बनाने की क्षमता SwiftUI की एक शक्तिशाली विशेषता है। इस लेख में, हम उदाहरणों को शामिल करेंगे कि कैसे इस सुविधा का उपयोग यूआई के निर्माण को इतना आसान बनाने के लिए किया जा सकता है। यदि आप SwiftUI में ViewModifiers और कस्टम बनाने के तरीके से परिचित नहीं हैं, तो आप उनके बारे में यहाँ पढ़ सकते हैं
इस लेख का लक्ष्य SwiftUI में कस्टम संशोधक और शैलियों को बनाने के कुछ अलग-अलग तरीकों को कवर करना है और एक साफ और सुसंगत अंतिम आउटपुट प्राप्त करते हुए यूआई को और अधिक घोषणात्मक बनाने के लिए उनका उपयोग कैसे किया जा सकता है।
अंतिम यूआई जिसे हम बनाना चाहते हैं वह यह है:
आइए स्क्रीन पर सभी अलग-अलग घटकों पर विचार करें:
यदि आप इस स्क्रीन को बिना किसी संशोधक के बनाते हैं, तो कोड कुछ इस तरह दिखाई देगा:
struct ContentView: View { var body: some View { VStack (alignment: .leading) { Image("feature") .resizable() .aspectRatio(contentMode: .fill) .frame(minWidth: 0, maxWidth: .infinity) .frame(height: 220) .cornerRadius(12) .padding(.bottom, 12) Text("Custom ViewModifiers in SwiftUI are the best!") .foregroundColor(Color("titleTextColor")) .font(.system(size: 20, weight: .bold)) .padding(.bottom, 12) Text("Custom ViewModifiers in SwiftUI let you create resuable styles that can be applied to all your views") .foregroundColor(Color("bodyTextColor")) .font(.system(size: 14, weight: .medium)) Spacer() Button(action: { }) { Text("Label") .font(.system(size: 14, weight: .medium)) } .frame(minWidth: 0, maxWidth: .infinity) .padding(.horizontal, 10) .padding(.vertical, 12) .background(Color.blue) .foregroundColor(Color.white) .cornerRadius(12) } .padding(.all, 16) } }
कुछ तत्वों के लिए स्टाइलिंग (उदाहरण के लिए शीर्षक और विवरण टेक्स्ट) को डुप्लिकेट करना होगा
कुछ सामान्य स्टाइल (एलिमेंट पैडिंग, कॉर्नर रेडियस आदि) में कई जगहों पर बदलाव करने होंगे
अब आप इस समस्या को UIKit तरीके से कस्टम व्यू बनाकर हल कर सकते हैं, लेकिन मैं इस दृष्टिकोण का प्रशंसक नहीं हूं क्योंकि इसमें बिल्ट-इन व्यू से दूर जाना शामिल है और नए टीम के सदस्यों को ऑनबोर्ड करना अधिक घर्षण बनाता है। कुछ सार्वभौमिक दृश्य संशोधक को परिभाषित करने का एक आसान तरीका होगा जिसे शैलियों के बजाय स्वयं लागू किया जा सकता है।
आइए हमें आवश्यक सामान्य स्टाइल को तोड़ दें:
चलो कोने त्रिज्या से शुरू करते हैं:
struct CommonCornerRadius: ViewModifier { func body(content: Content) -> some View { content .cornerRadius(12) } }
यह एक बल्कि सरल है, यह हमें तत्वों के लिए एक सार्वभौमिक कोने की त्रिज्या लागू करने की अनुमति देता है। यह कस्टम दृश्य बनाए बिना या कोडबेस में कई बदलाव किए बिना विश्व स्तर पर ऐप शैलियों को बदलना आसान बनाता है।
struct FullWidthModifier: ViewModifier { func body(content: Content) -> some View { content .frame(minWidth: 0, maxWidth: .infinity) } }
यह पूर्ण-चौड़ाई वाले दृश्यों को लागू करना आसान बनाता है, मैन्युअल रूप से .frame
जोड़ने की आवश्यकता नहीं है!
struct TitleTextModifier: ViewModifier { func body(content: Content) -> some View { content .foregroundColor(Color("titleTextColor")) .font(.system(size: 20, weight: .bold)) } } struct BodyTextModifier: ViewModifier { func body(content: Content) -> some View { content .foregroundColor(Color("bodyTextColor")) .font(.system(size: 14, weight: .medium)) } }
यह सामान्य टेक्स्ट स्टाइलिंग की अनुमति देगा, आम तौर पर आप या तो कस्टम टेक्स्ट घटक या यूटिलिटी फ़ंक्शंस बनाएंगे और कोड के माध्यम से UI घटक जोड़ेंगे।
extension Image { func aspectFill() -> some View { self .resizable() .aspectRatio(contentMode: .fill) } }
ठीक है, आप समझ गए...यह कोई कस्टम व्यू मॉडिफायर नहीं है बल्कि एक साधारण एक्सटेंशन है। ऐसा इसलिए है क्योंकि ViewModifiers सेब सामान्य दृश्यों के लिए और कुछ फ़ंक्शन जैसे resizable
केवल छवियों पर लागू होते हैं, एक्सटेंशन और कस्टम संशोधक के संयोजन का उपयोग करने से इससे बचने में मदद मिलती है।
struct FullWidthButtonStyle: ButtonStyle { func makeBody(configuration: Configuration) -> some View { configuration.label .fullWidth() .foregroundColor(Color.white) .font(.system(size: 14, weight: .medium)) .padding(.horizontal, 10) .padding(.vertical, 12) .background(configuration.isPressed ? Color.blue.opacity(0.2) : Color.blue) } } struct FullWidthButton: ViewModifier { func body(content: Content) -> some View { content .buttonStyle(FullWidthButtonStyle()) } }
अंत में, यह बटन के लिए है, ध्यान दें कि जबकि हम उसी प्रभाव को पूरा करने के लिए बस एक व्यू मॉडिफायर बना सकते थे, टैप करने पर बटन का स्वरूप नहीं बदला होता। ऐसा इसलिए है क्योंकि एक बटन पर .background
सेट करने से यह उस पृष्ठभूमि को टैप और अनटैप्ड दोनों स्थितियों में उपयोग करने के लिए बाध्य करता है। ButtonStyle
हमें बटन की अपारदर्शिता को इस आधार पर बदलने देता है कि इसे दबाया गया है या नहीं।
अब सुविधा के लिए, मुझे इन संशोधक का उपयोग करने वाले एक्सटेंशन बनाना पसंद है:
extension View { func commonCornerRadius() -> some View { modifier(CommonCornerRadius()) } func fullWidth() -> some View { modifier(FullWidthModifier()) } func title() -> some View { modifier(TitleTextModifier()) } func body() -> some View { modifier(BodyTextModifier()) } func fullWidthButton() -> some View { modifier(FullWidthButton()) } } extension Image { func aspectFill() -> some View { self .resizable() .aspectRatio(contentMode: .fill) } }
struct ContentView: View { var body: some View { VStack (alignment: .leading) { Image("feature") .aspectFill() .fullWidth() .frame(height: 220) .commonCornerRadius() .padding(.bottom, 12) Text("Custom ViewModifiers in SwiftUI are the best!") .title() .padding(.bottom, 12) Text("Custom ViewModifiers in SwiftUI let you create resuable styles that can be applied to all your views") .body() Spacer() Button(action: { }) { Text("Awesome") } .fullWidthButton() .commonCornerRadius() } .padding(.all, 16) } }
ज्यादा साफ! अब पहली नज़र में, यह शैलियों को मैन्युअल रूप से सेट करने की तुलना में अधिक कोड और प्रयास की तरह लगता है, लेकिन लंबे समय में, यह बहुत प्रयास बचाएगा। व्यक्तिगत रूप से, यह दृष्टिकोण स्टाइल के व्यू-बाय-व्यू के आधार पर सामान्य संशोधक पर अधिक भरोसा करके आपके ऐप की शैली को और अधिक सुसंगत बनाने के लिए प्रोत्साहित करता है।
और वह इसके बारे में है! उम्मीद है, यह आपको अपने ऐप्स को तेज़ी से और आसानी से बनाने में मदद करता है, एक और लाभ यह है कि इन संशोधकों को आपके किसी भी ऐप में छोड़ा जा सकता है और इसके स्टाइल दिशानिर्देशों से मेल खाने के लिए इसे ट्वीक किया जा सकता है। मैं इसे और भी आगे ले जाने के लिए एक पुस्तकालय पर काम कर रहा हूं, आप इसे यहां देख सकते हैं (पुनश्च: इसे लिखने के समय पुस्तकालय सुपर शुरुआती चरण में है, रेपो खाली है: पी लेकिन देखते रहें)