ios - प्रत्येक UITableViewCell के लिए दृश्य-मॉडल बनाना




swift design-patterns (2)

जब तक आपके पास एक विशिष्ट समस्या नहीं होती है जिसे Model-View-ViewModel साथ हल किया जाता है, तब इसे 'सर्वोत्तम प्रथाओं' के लिए अपनाने का प्रयास करने से बहुत अधिक अनावश्यक जटिलताओं को शुरू करना होगा।

आपका डेटा स्रोत वह है जो आपकी तालिका को लोकप्रिय बनाने के लिए ज़िम्मेदार है। आपके डेटास्रोत के अलावा अन्य कोई भी contacts संदर्भ की आवश्यकता नहीं है क्योंकि यह इस डेटा के साथ आपकी तालिका को अपडेट करेगा।

View Models केवल जब आप जटिल UI के इंटरैक्शन और अपडेट करने की आवश्यकता होती है तब ही आते हैं। वीएम आपके दृष्टिकोण की स्थिति को समझाते हैं, जैसी चीज़ें ...

  1. टेक्स्टफ़ील्ड के मूल्य
  2. कौन से चेकबॉक्स / रेडियो बटन चुने गए हैं
  3. तत्वों का रंग
  4. एनीमेशन तर्क
  5. UI तत्वों के बीच निर्भरताएं

जब आपके व्यू में परिवर्तन किए जाते हैं, तो यूआई के माध्यम से उस Model को किए गए परिवर्तनों को प्रतिबिंबित करने के लिए अपने View Model आपके Model अपडेट करने (जब आवश्यक हो) के लिए ज़िम्मेदार होता है।

सभी ने कहा है कि, देखें मॉडल आईओएस में समझ नहीं आते हैं क्योंकि आईओएस MVC (मॉडल-व्यू-नियंत्रक) नामक डिजाइन पद्धति में View Controllers का उपयोग करता है I

मैं तालिका दृश्य के कक्षों के लिए दृश्य-मॉडल बनाने के साथ एक डिजाइन निर्णय पर फंस गया हूँ। प्रत्येक सेल के लिए डेटा डेटा स्रोत वर्ग ( Contacts की एक सरणी) द्वारा प्रदान किया गया है। MVVM केवल दृश्य-मॉडल मॉडल से बात कर सकता है, लेकिन यह आंकड़ा स्रोत को दृश्य-मॉडल में रखने के लिए समझ में नहीं आता है क्योंकि यह सभी कोशिकाओं के डेटा तक पहुंचाना संभव बनाता है, डेटा नियंत्रक को देखने नियंत्रक के रूप में भी गलत है डेटा के संदर्भ में नहीं होना चाहिए कुछ अन्य प्रमुख क्षण हैं:

  • प्रत्येक सेल को यह देखना होगा कि यह मॉडल का अपना उदाहरण है, साझा नहीं किया गया है
  • cellForRowAtindexPath को किसी दृश्य-मॉडल में नहीं रखा जाना चाहिए क्योंकि इसमें किसी भी UI संदर्भ नहीं होना चाहिए
  • देखें / देखें नियंत्रक के दृश्य-मॉडल को सेल के दृश्य-मॉडल के साथ सहभागिता नहीं करनी चाहिए

MVVM के रिश्ते में कोशिकाओं के लिए "डालें" डेटा स्रोत का सही तरीका क्या है? धन्यवाद।


मुझे कुछ सिद्धांत के साथ शुरू करें एमवीवीएम माइक्रोसॉफ्ट के सिल्वरलाइट और डब्लूपीएफ के लिए प्रस्तुति मॉडल (या एप्लीकेशन मॉडल) की विशेषज्ञता है। इस यूआई वास्तुशिल्प पैटर्न के पीछे मुख्य विचार हैं:

  • दृश्य भाग केवल एक ही है जो जीयूआई ढांचा पर निर्भर करता है। इसका मतलब यह है कि IOS के लिए, दृश्य नियंत्रक दृश्य का हिस्सा है।
  • दृश्य केवल दृश्य मॉडल से बात कर सकता है कभी मॉडल नहीं
  • दृश्य मॉडल दृश्य की स्थिति रखता है। इस स्थिति को देखने के मॉडल गुणों के माध्यम से देखने की पेशकश की जाती है। इन गुणों में केवल लेबल के मूल्य ही नहीं होते हैं, बल्कि अन्य दृश्य संबंधित जानकारी जैसे कि सहेज बटन सक्षम है या रेटिंग दृश्य के लिए रंग है। लेकिन राज्य की जानकारी यूआई फ्रेमवर्क स्वतंत्र होना चाहिए। इसलिए IOS के मामले में, रंग के लिए संपत्ति एक एन्यूम होना चाहिए, उदाहरण के लिए, UIColor की बजाय।
  • दृश्य मॉडल उन तरीकों को भी प्रदान करता है जो UI कार्यों का ध्यान रखेगा। यह क्रिया मॉडल से बात करेगी, लेकिन वे सीधे दृश्य से संबंधित डेटा को बदलते नहीं हैं इसके बजाय, यह मॉडल से बात करता है और आवश्यक बदलावों के लिए पूछता है
  • मॉडल को स्वायत्त होना चाहिए, अर्थात आप कमांड लाइन एप्लिकेशन और यूआई इंटरफ़ेस के लिए मॉडल के समान कोड का उपयोग करने में सक्षम होना चाहिए। यह सभी व्यावसायिक तर्कों का ख्याल रखेगा
  • मॉडल को देखने के मॉडल के बारे में नहीं पता है तो देखने के मॉडल में परिवर्तन एक प्रेक्षण तंत्र के माध्यम से प्रचारित होते हैं। आईओएस के लिए और सादे NSObject subclasses या यहां तक ​​कि कोर डेटा के साथ एक मॉडल, केवीओ उस के लिए इस्तेमाल किया जा सकता है (स्विफ्ट के लिए भी)
  • मॉडल में बदलाव के बारे में दृश्य मॉडल जान ले जाने के बाद, यह उस राज्य को अपडेट कर लेना चाहिए जो इसे रखता है (यदि आप मूल्य प्रकारों का उपयोग करते हैं, तो इसे एक अपडेट किया जाना चाहिए और इसे बदलना चाहिए)।
  • दृश्य मॉडल दृश्य के बारे में नहीं जानता है इसकी मूल धारणा में यह डेटा बाइंडिंग का उपयोग करता है, जो आईओएस के लिए उपलब्ध नहीं है। तो देखने के मॉडल में परिवर्तन एक प्रेक्षण तंत्र के माध्यम से प्रचारित होते हैं। आप यहां केवीओ का उपयोग भी कर सकते हैं, या जैसा कि आप इस प्रश्न में उल्लेख करते हैं, एक सरल प्रतिनिधिमंडल पैटर्न, स्विफ्ट प्रॉपर्टी पर्यवेक्षक के साथ मिलकर बेहतर होगा। कुछ लोग रिएक्टिव फ्रेमवर्क पसंद करते हैं, जैसे कि RxSwift, ReactiveCocoa, या स्विफ्ट बॉन्ड।

जैसा कि आपने उल्लेख किया है, लाभ हैं:

  • चिंताओं का बेहतर जुदाई
  • UI आजादी: अन्य UI पर आसान प्रवास
  • चिंता की जुदाई और कोड की डिकप्लेड प्रकृति के कारण बेहतर परीक्षण योग्यता।

तो आपके प्रश्न पर वापस आ रहा है, UITableViewDataSource प्रोटोकॉल का कार्यान्वयन, आर्किटेक्चर के दृश्य भाग से संबंधित है, क्योंकि UI फ़्रेमवर्क पर निर्भरता के कारण। ध्यान दें कि आपके कोड में उस प्रोटोकॉल का उपयोग करने के लिए, उस फ़ाइल को UIKit आयात करना चाहिए साथ ही tableView(:cellForRowAt:) दृश्य tableView(:cellForRowAt:) कि एक दृश्य रिटर्न देता है जो UIKit पर भारी निर्भर है।

फिर, आपके Contacts सरणी, जो वास्तव में आपके मॉडल है, को देखने या डेटा (या अन्यथा) के माध्यम से संचालित नहीं किया जा सकता है। इसके बजाय आप अपने टेबल व्यू नियंत्रक के लिए एक दृश्य मॉडल पास करते हैं, कि, सरलतम मामले में, दो गुण हैं (मैं सुझाता हूं कि वे संग्रहीत हैं, गणना की गई संपत्ति नहीं)। उनमें से एक वर्गों की संख्या है और दूसरा खंड प्रति वर्ग की संख्या है:

var numberOfSections: Int = 0
var rowsPerSection: [Int] = []

दृश्य मॉडल को मॉडल के संदर्भ के साथ आरंभ किया जाता है और प्रारंभिक रूप में अंतिम चरण के रूप में यह उन दो गुणों के मान सेट करता है।

दृश्य नियंत्रक में डेटा स्रोत दृश्य मॉडल के डेटा का उपयोग करता है:

override func numberOfSections(in tableView: UITableView) -> Int {
    return viewModel.numberOfSections
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return viewModel.rowsPerSection[section]
}

अंत में आप प्रत्येक कोशिका के लिए एक भिन्न दृश्य मॉडल स्ट्रेट कर सकते हैं:

struct ContactCellViewModel {
    let name: String

    init(contact: Contact) {
        name = contact.name ?? ""
    }
}

और UITableViewCell उपवर्ग को पता होगा कि उस संरचना का उपयोग कैसे करें:

class ContactTableViewCell: UITableViewCell {
    
    var viewModel: ContactCellViewModel!

    func configure() {
        textLabel!.text = viewModel.name
    }
}

प्रत्येक कोशिका के लिए इसी दृश्य मॉडल के लिए, तालिका दृश्य व्यू मॉडल उन तरीकों को प्रदान करेगा जो उन्हें उत्पन्न करता है, और इसका उपयोग दृश्य मॉडलों की श्रेणी को पॉप्युलेट करने के लिए किया जा सकता है:

func viewModelForCell(at index: Int) -> ContactCellViewModel {
    return ContactCellViewModel(contact: contacts[index])
}

जैसा कि आप देख सकते हैं कि यहां केवल मॉडल ही हैं (केवल अपने Contacts सरणी), और विचार केवल दृश्य मॉडल से बात करते हैं।

उम्मीद है की यह मदद करेगा।





mvvm