स्क्रैच से एक शॉपिंग सूची आवेदन निर्माण: भाग 2
Hindi (हिंदी) translation by Afiff Soebarkah (you can also view the original English article)
पिछले कम में, हम खरीदारी की सूची आवेदन के लिए नींव रखी । इस पाठ के पहले भाग में, हम उपयोगकर्ता को सूची से आइटम संपादित करने और हटाने में सक्षम करके अनुप्रयोग को परिष्कृत करेंगे । इस पाठ के दूसरे भाग में, हम खरीदारी सूची बनाने के लिए सूची से आइटम का चयन करने की क्षमता जोड़ते हैं ।
बाह्यरेखा
जैसा कि मैंने पिछले लेख में उल्लेख किया है, खरीदारी की सूची आवेदन के मुख्य सुविधाओं में से एक मदों की एक सूची का प्रबंधन है । हम एक महान काम किया है अब तक, लेकिन उपयोगकर्ता को संपादित करें और सूची से आइटम, जो इस ट्यूटोरियल के पहले भाग का ध्यान केंद्रित किया जाएगा नष्ट करने की क्षमता होनी चाहिए । दूसरे भाग में, हम आइटम की सूची से आइटम का चयन करके एक शॉपिंग सूची बनाने, शॉपिंग सूची आवेदन की दूसरी कोर सुविधा को लागू करेगा ।
9. आइटम हटाना
सूची से आइटम हटाना उपयोगकर्ता अनुभव और समग्र प्रयोज्य के मामले में एक महत्वपूर्ण इसके अतिरिक्त है । इस क्षमता को जोड़ना शामिल है:
- आइटम को दृश्य नियंत्रक के आइटम गुण से निकाल रहा है
- तालिका दृश्य का अद्यतन करना
- डिस्क में परिवर्तनों को सहेजना
चलो देखते है कि यह कैसे काम करता है व्यवहार में ।
हम पहले नेविगेशन पट्टी करने के लिए एक संपादित करें बटन जोड़ने की जरूरत है । दृश्य नियंत्रक की viewDidLoad विधि में, UIBarButtonItem की एक आवृत्ति बनाएँ, और इसे दृश्य नियंत्रक की navigationItem गुण rightBarButtonItem गुण के लिए असाइन करें ।
पिछले पाठ के रूप में, हम initWithBarButtonSystemItem:
लक्ष्य: क्रिया: प्रारंभिक पद्धति को कॉल करके एक बार बटन आइटम बनाते हैं । पहले पैरामीटर है कि हम पास UIBarButtonSystemItemEdit
है । इसके अलावा, हम लक्ष्य के रूप में स्वयं से गुजारें और editItems:
के लिए कार्रवाई सेट ।
- (void)viewDidLoad { [super viewDidLoad]; // NSLog(@"Items > %@", self.items); // Register Class for Cell Reuse [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:CellIdentifier]; // Create Add Button self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addItem:)]; // Create Edit Button self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:@selector(editItems:)]; }
editItems:
के कार्यांवयन कार्रवाई कोड की केवल एक पंक्ति के रूप में आप नीचे देख सकते है । जब भी उपयोगकर्ता संपादित करें बटन टैप करता है, तो तालिका दृश्य को संपादन मोड में या बाहर टॉगल कर लिया जाता है. हम एक छोटी चाल का उपयोग करके यह करते हैं । हम तालिका दृश्य पूछें कि क्या यह वर्तमान में संपादन मोड में है, जो एक BOOL
मान देता है, और व्युत्क्रम लौटाए गए मान (हां
नहीं
हो जाता है और इसके विपरीत) । विधि हम मेज देखने पर कहते है setEditing: एनिमेटेड:
, जो एक विशेष सेटर है कि एक एनीमेशन पैरामीटर स्वीकार करता है ।
- (void)editItems:(id)sender { [self.tableView setEditing:![self.tableView isEditing] animated:YES]; }
आप iOS सिम्युलेटर में शॉपिंग सूची आवेदन चलाते हैं और संपादित करें बटन नल, आप तालिका दृश्य में और संपादन मोड से बाहर toggled जा रहा है देखना चाहिए.



UITableViewDataSource
प्रोटोकॉल की दो विधियाँ किसी तालिका दृश्य में संपादन को सक्षम करने के लिए महत्वपूर्ण हैं:
tableView: canEditRowAtIndexPath:
tableView: commitEditingStyle: forRowAtIndexPath:
जब उपयोगकर्ता संपादित करें बटन को टैप करते हैं, तो तालिका दृश्य डेटा स्रोत को tableView:canEditRowAtIndexPath:
का संदेश भेजकर अपने डेटा स्रोत से पूछता है कि कौन-सी पंक्तियाँ संपादन योग्य हैं. जब हां किसी विशेष अनुक्रमणिका पथ के लिए दिया जाता है, तो तालिका दृश्य तालिका दृश्य के कक्ष को उस संगत पंक्ति के लिए निर्देश देता है, जिसे उसे टेबल दृश्य के संपादन मोड के आधार पर या संपादन मोड में टॉगल करने की आवश्यकता होती है ।
व्यवहार में, इसका अर्थ यह है कि तालिका दृश्य कक्ष इसके संपादन नियंत्रणों को दिखाता या छुपाता है । इस अवधारणा को लागू करने के द्वारा सबसे अच्छा समझ है tableView:canEditRowAtIndexPath:
विधि के रूप में नीचे दिखाया गया है ।
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { if ([indexPath row] == 1) { return NO; } return YES; }
tableView:canEditRowAtIndexPath:
के ऊपर लागू दूसरी पंक्ति के अपवाद के साथ तालिका दृश्य में प्रत्येक पंक्ति को संपादित करने के लिए उपयोगकर्ता को सक्षम करता है । आईओएस सिम्युलेटर में आवेदन चलाने के लिए और यह एक कोशिश दे ।



शॉपिंग सूची अनुप्रयोग के लिए, उपयोगकर्ता को तालिका दृश्य में प्रत्येक पंक्ति को संपादित करने में सक्षम होना चाहिए, जिसका अर्थ है कि tableView: canEditRowAtIndexPath:
हमेशा हाँ वापस के रूप में नीचे illustrated होना चाहिए ।
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { return YES; }
आपने देखा होगा कि तालिका दृश्य में किसी पंक्ति को हटाने का प्रयास करने पर कुछ नहीं होता है । पहेली अभी तक समाप्त नहीं हुआ है । जब भी उपयोगकर्ता किसी पंक्ति के हटाएँ बटन को टैप करते हैं, तो तालिका दृश्य अपने डेटा स्रोत को tableView:commitEditingStyle:forRowAtIndexPath:
का संदेश भेजता है. इसी विधि का दूसरा तर्क यह नोट करें कि उपयोगकर्ता ने किस प्रकार की कार्रवाई की है, किसी पंक्ति को संमिलित या हटा रहा है । शॉपिंग सूची अनुप्रयोग केवल तालिका दृश्य से पंक्तियों को हटाने के लिए समर्थन प्रदान करेगा.
किसी तालिका दृश्य से पंक्तियों को हटाना शामिल है:
- दृश्य नियंत्रक के आइटम गुण से संबंधित आइटम को हटाना
- संगत पंक्ति को हटा कर तालिका दृश्य का अद्यतन करना
चलो tableView:commitEditingStyle: forRowAtIndexPath:
के कार्यांवयन का निरीक्षण । विधि क्या संपादन शैली UITableViewCellEditingStyleDelete
के बराबर है के रूप में हम केवल उपयोगकर्ता तालिका दृश्य से पंक्तियाँ हटाने के लिए अनुमति देने के लिए चाहते हैं कि जाँच द्वारा प्रारंभ होता है ।
यदि संपादन शैली UITableViewCellEditingStyleDelete
के बराबर है, तो आइटम सरणी से संबंधित आइटम निकाल दिया जाता है, तालिका दृश्य से संबंधित पंक्ति हटाई जाती है, और आइटंस की अद्यतित सूची डिस्क पर सहेजी जाती है ।
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { // Delete Item from Items [self.items removeObjectAtIndex:[indexPath row]]; // Update Table View [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationRight]; // Save Changes to Disk [self saveItems]; } }
अनुप्रयोग को हटाएँ कार्यक्षमता का परीक्षण करने के लिए iOS सिम्युलेटर में चलाएँ । बाहर निकलें और सत्यापित करें कि आइटम स्थायी रूप से सूची से हटा रहे हैं करने के लिए अनुप्रयोग को फिर से शुरू करने के लिए मत भूलना ।
10. संपादन आइटम
हम संपादन मदों के लिए TSPAddItemViewController
वर्ग का पुनः प्रयोग सकता है, लेकिन दोनों को जोड़ने और संपादन मदों के लिए एक दृश्य नियंत्रक वर्ग का उपयोग कर अक्सर कार्यांवयन इतना अधिक है कि मैं आम तौर पर अंत में एक अलग UIViewController
उपवर्ग बनाने के अधिक जटिल कर सकते है आइटम संपादन के लिए । इस कार्यांवयन और उपयोगकर्ता इंटरफ़ेस के संदर्भ में कुछ ओवरलैप में शुरू में परिणाम होगा, लेकिन यह हमें सड़क के नीचे और अधिक लचीलापन दे देंगे ।
संपादन दृश्य नियंत्रक बना रहा है
एक नया UIViewController
उपवर्ग बनाएं और इसे नाम TSPEditItemViewController
। TSPAddItemViewController
और TSPEditItemViewController
वर्गों के शीर्ष लेख फ़ाइलें बहुत समान हैं ।
#import <UIKit/UIKit.h> @class TSPItem; @protocol TSPEditItemViewControllerDelegate; @interface TSPEditItemViewController : UIViewController @property IBOutlet UITextField *nameTextField; @property IBOutlet UITextField *priceTextField; @property TSPItem *item; @property (weak) id<TSPEditItemViewControllerDelegate> delegate; @end @protocol TSPEditItemViewControllerDelegate <NSObject> - (void)controller:(TSPEditItemViewController *)controller didUpdateItem:(TSPItem *)item; @end
UIKit framework के शीर्ष लेख को आयात करने के बाद, एक अग्रेषित वर्ग और प्रोटोकॉल घोषणा जोड़ा जाता है । वर्ग के इंटरफेस है कि TSPAddItemViewController
वर्ग के समान है । मुख्य अंतर उस आइटम को संग्रहीत करने के लिए किसी गुण की घोषणा है जिसे संपादित किया जा रहा है ।
शीर्ष लेख फ़ाइल TSPEditItemViewControllerDelegate
प्रोटोकॉल की घोषणा के साथ समाप्त होता है । प्रोटोकॉल घोषणा में एक विधि जो कहा जाता है जब कोई आइटम अद्यतन किया जाता है । विधि दृश्य नियंत्रक और अद्यतन किए गए आइटम के रूप में इसके तर्क स्वीकार करता है ।
मुख्य स्टोरीबोर्ड खोलें, ऑब्जेक्ट लायब्रेरी से कोई UIViewController
आवृत्ति को खींचें, उसके वर्ग को TSPEditItemViewController
पर सेट करें, और सूची दृश्य नियंत्रक से एक मैंयुअल पुश segue बनाने के लिए आइटम दृश्य नियंत्रक संपादित करें, इसे नामकरण EditItemViewController
।



दो UITextField इंस्टेंस ऑब्जेक्ट लायब्रेरी से दृश्य नियंत्रक के दृश्य में खींचें और उंहें नीचे चित्र में दिखाए गए के रूप में स्थिति । शीर्ष पाठ फ़ील्ड का चयन करें, विशेषताएँ निरीक्षक खोलें, और प्लेसहोल्डर फ़ील्ड में नाम दर्ज करें । निचली पाठ फ़ील्ड का चयन करें और, विशेषताएँ निरीक्षक में, इसके प्लेसहोल्डर पाठ को मूल्य और कुंजीपटल सेट करने के लिए संख्या पैड सेट । नियंत्रक ऑब्जेक्ट दृश्य का चयन करें, कनेक्शन निरीक्षक खोलें, और उपयोगकर्ता इंटरफ़ेस में संगत पाठ फ़ील्ड के लिए nameTextField
और priceTextField
आउटलेट्स से कनेक्ट हों ।



दृश्य नियंत्रक की viewDidLoad
पद्धति में, सहेजें बटन बनाएं जैसा कि हमने TSPAddItemViewController
वर्ग में किया था ।
- (void)viewDidLoad { [super viewDidLoad]; // Create Save Button self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(save:)]; }
सहेजें के कार्यांवयन: कार्रवाई बहुत एक हम TSPAddItemViewController
वर्ग में कार्यांवित के समान है । हालांकि, वहां कुछ सूक्ष्म मतभेद है कि मैं कहना चाहता हूं ।
- (void)save:(id)sender { NSString *name = [self.nameTextField text]; float price = [[self.priceTextField text] floatValue]; // Update Item [self.item setName:name]; [self.item setPrice:price]; // Notify Delegate [self.delegate controller:self didUpdateItem:self.item]; // Pop View Controller [self.navigationController popViewControllerAnimated:YES]; }
प्रतिनिधि के लिए नाम और मूल्य मान को पास करने के बजाय, हम सीधे आइटम अद्यतन और दृश्य नियंत्रक के प्रतिनिधि के लिए अद्यतन किए गए आइटम पास । दृश्य नियंत्रक किसी नेविगेशन नियंत्रक का चाइल्ड दृश्य नियंत्रक है, क्योंकि हम इसे नेविगेशन स्टैक की popping द्वारा दृश्य नियंत्रक को ख़ारिज करें ।
आइटम दृश्य नियंत्रक संपादित करें दिखा रहा है
कुछ ही मिनटों में, हम उस कार्यक्षमता को कार्यान्वित करेंगे जो उपयोगकर्ता को शॉपिंग सूची में जोड़ने के लिए सूची दृश्य नियंत्रक से आइटम्स का चयन करने की अनुमति देती है. उपयोगकर्ता सूची दृश्य में एक पंक्ति टैप करके ऐसा करने में सक्षम हो जाएगा । सवाल तो यह उठता है कि कैसे उपयोगकर्ता एक आइटम संपादित अगर एक पंक्ति दोहन करने में सक्षम हो जाएगा खरीदारी की सूची में एक आइटम जोड़ने के लिए आरक्षित है?
UIKit फ्रेमवर्क बिल्कुल इस प्रयोग के मामले के लिए एक विस्तार प्रकटीकरण बटन प्रदान करता है । एक विस्तार प्रकटीकरण बटन एक छोटे, नीले एक मेज दृश्य सेल के अधिकार पर तैनात धरण है । तालिका दृश्य कक्ष में एक विस्तार प्रकटीकरण बटन जोड़ने के लिए, हमें तालिका दृश्य पर फिर से tableView:cellForRowAtIndexPath:
सूची दृश्य नियंत्रक में विधि और नीचे दिखाए गए अनुसार इसे संशोधित करें।
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // Dequeue Reusable Cell UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; // Fetch Item TSPItem *item = [self.items objectAtIndex:[indexPath row]]; // Configure Cell [cell.textLabel setText:[item name]]; [cell setAccessoryType:UITableViewCellAccessoryDetailDisclosureButton]; return cell; }
प्रत्येक तालिका दृश्य कक्ष में एक accessoryType गुण है । नीचे कार्यांवयन में, हम इसे UITableViewCellAccessoryDetailDisclosureButton के लिए सेट । जैसा कि आप देखा हो सकता है, एप्पल में इंजीनियरों कम नाम पसंद नहीं है ।
विवरण प्रकटीकरण बटन टैप किए जाने पर तालिका दृश्य प्रतिनिधि को सूचित कैसे करता है? आश्चर्य की बात है, UITableViewDelegate प्रोटोकॉल tableView: accessoryButtonTappedForRowWithIndexPath: विधि इस प्रयोजन के लिए परिभाषित करता है । इसके क्रियान्वयन पर एक नजर डालें ।
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath { // Fetch Item TSPItem *item = [self.items objectAtIndex:[indexPath row]]; if (item) { // Update Selection [self setSelection:item]; // Perform Segue [self performSegueWithIdentifier:@"EditItemViewController" sender:self]; } }
हम आइटम गुण से सही आइटम प्राप्त करते है और इसे चयन में संग्रहीत करते हैं, सूची दृश्य नियंत्रक का एक निजी गुण जिसे हम एक क्षण में घोषित करेंगे । हम तो पह EditItemViewController के साथ segue करते हैं.
इससे पहले कि हम prepareForSegue के कार्यांवयन का अद्यतन करें: प्रेषक:, हमें चयनित आइटम को संग्रहीत करने के लिए निजी गुण घोषित करने की आवश्यकता है ।
#import "TSPListViewController.h" #import "TSPItem.h" @interface TSPListViewController () @property NSMutableArray *items; @property TSPItem *selection; @end
हम भी TSPListViewController. h में TSPEditItemViewController वर्ग के हैडर फ़ाइल आयात और TSPEditItemViewControllerDelegate प्रोटोकॉल के लिए TSPListViewController वर्ग के अनुरूप की जरूरत है ।
#import <UIKit/UIKit.h> #import "TSPAddItemViewController.h" #import "TSPEditItemViewController.h" @interface TSPListViewController : UITableViewController <TSPAddItemViewControllerDelegate, TSPEditItemViewControllerDelegate> @end
prepareForSegue के अद्यतन कार्यांवयन: प्रेषक: बहुत आसान है के रूप में आप नीचे देख सकते हैं । हम आइटम दृश्य नियंत्रक संपादित करें और इसके प्रतिनिधि और आइटम गुण सेट करने के लिए एक संदर्भ मिलता है ।
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.identifier isEqualToString:@"AddItemViewController"]) { // Destination View Controller UINavigationController *nc = (UINavigationController *)segue.destinationViewController; // Fetch Add Item View Controller TSPAddItemViewController *vc = [nc.viewControllers firstObject]; // Set Delegate [vc setDelegate:self]; } else if ([segue.identifier isEqualToString:@"EditItemViewController"]) { // Fetch Edit Item View Controller TSPEditItemViewController *vc = (TSPEditItemViewController *)segue.destinationViewController; // Set Delegate [vc setDelegate:self]; [vc setItem:self.selection]; } }
TSPEditItemViewController वर्ग का क्रियान्वयन लगभग पूरा हो गया है । इसके viewDidLoad विधि में, हम पाठ फ़ील्ड आइटम गुण का डेटा के साथ पॉप्युलेट । setText: एक पाठ फ़ील्ड की विधि केवल एक NSString आवृत्ति को स्वीकार करता है, क्योंकि हम इसे priceTextField में प्रदर्शित करने के लिए एक स्ट्रिंग में आइटम के मूल्य गुण का फ़्लोट करें मान लपेटने की आवश्यकता है ।
- (void)viewDidLoad { [super viewDidLoad]; // Create Save Button self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(save:)]; // Populate Text Fields if (self.item) { [self.nameTextField setText:[self.item name]]; [self.priceTextField setText:[NSString stringWithFormat:@"%f", [self.item price]]]; } }
प्रतिनिधि प्रोटोकॉल को अपनाने
TSPEditItemViewControllerDelegate प्रोटोकॉल को अपनाने नियंत्रक को लागू करने के लिए सीमित है: didUpdateItem: विधि के रूप में नीचे दिखाया गया है । यह आपको आश्चर्य हो सकता है कि हम तालिका दृश्य के डेटा स्रोत का अद्यतन नहीं करते हैं. सभी हम प्रतिनिधि विधि में है तालिका दृश्य की एक पंक्ति पुनः लोड है ।
- (void)controller:(TSPEditItemViewController *)controller didUpdateItem:(TSPItem *)item { // Fetch Item for (int i = 0; i < [self.items count]; i++) { TSPItem *anItem = [self.items objectAtIndex:i]; if ([[anItem uuid] isEqualToString:[item uuid]]) { // Update Table View Row NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0]; [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; } } // Save Items [self saveItems]; }
कारण है कि हम तालिका दृश्य के डेटा स्रोत को अद्यतन करने की आवश्यकता नहीं है, तो आइटम सरणी, अद्यतन किए गए आइटम संपादित करें आइटम दृश्य नियंत्रक के लिए संदर्भ द्वारा दिया गया है । दूसरे शब्दों में, आइटम दृश्य नियंत्रक का अद्यतन संपादित करें ऑब्जेक्ट आइटम सरणी में शामिल है जो एक ही ऑब्जेक्ट है । यह वस्तुओं और संकेत के साथ काम करने का अच्छा लाभ में से एक है ।
यह सुनिश्चित करने के लिए आइटंस की सूची सहेजना न भूलें कि संपादन डिस्क पर लिखे गए हैं । संपादन कार्यक्षमता का परीक्षण करने के लिए अनुप्रयोग चलाएं ।
11. शॉपिंग सूची दृश्य नियंत्रक बनाना
हम खरीदारी सूची दृश्य नियंत्रक के डेटा स्रोत का पता लगाने से पहले, के साथ काम करने के लिए कुछ मचान पैदा करते हैं । एक नया UITableViewController उपवर्ग बनाएं और इसे नाम TSPShoppingListViewController ।
नए वर्ग के कार्यांवयन फ़ाइल खोलें और वर्ग एक्सटेंशन के लिए NSArray प्रकार के दो निजी गुण जोड़ें:
- आइटम, जो आइटम की पूरी सूची में शामिल होंगे
- shoppingList, जो केवल शॉपिंग सूची के आइटम शामिल होंगे
जब से हम दोनों संपत्तियों के सेटर तरीकों की अवहेलना की जाएगी, हम को परमाणु के रूप में संपत्तियों की घोषणा की है । अब के लिए इस के सटीक अर्थ के बारे में चिंता मत करो ।
#import <UIKit/UIKit.h> @interface TSPShoppingListViewController : UITableViewController @property (nonatomic) NSArray *items; @property (nonatomic) NSArray *shoppingList; @end
इस विचार को हर बार एक परिवर्तन सूची में किया जाता है आइटम की सूची लोड और फिर मदों की सूची को पार्स और केवल उन मदों जो उनके inShoppingList संपत्ति है निकालने के लिए हां सेट है । उन आइटंस को shoppingList सरणी में जोड़ा जाएगा ।
एक अंय विकल्प के लिए एक अलग फ़ाइल में खरीदारी की सूची की दुकान होगी, लेकिन इस दृष्टिकोण के नकारात्मक पक्ष यह होगा कि हम सूची दृश्य नियंत्रक में आइटम और खरीदारी की सूची में आइटम सिंक्रनाइज़ रखना होगा । यह मुसीबत के लिए पूछ रहा है अगर तुम मुझसे पूछो ।
कस् Setters
मदों और shoppingList के सेटर तरीकों हमारे लिए भारी उठाने का सबसे करना होगा । setItems के कार्यांवयन पर एक नज़र रखना: । जब भी _items आवृत्ति चर अद्यतन किया जाता है (एक नया मान के साथ सेट करें), buildShoppingList विधि दृश्य नियंत्रक पर कहा जाता है ।
- (void)setItems:(NSArray *)items { if (_items != items) { _items = items; // Build Shopping List [self buildShoppingList]; } }
चलो देखते है कि buildShoppingList विधि की तरह लग रहा है ।
- (void)buildShoppingList { NSMutableArray *buffer = [[NSMutableArray alloc] init]; for (int i = 0; i < [self.items count]; i++) { TSPItem *item = [self.items objectAtIndex:i]; if ([item inShoppingList]) { // Add Item to Buffer [buffer addObject:item]; } } // Set Shopping List self.shoppingList = [NSArray arrayWithArray:buffer]; }
buildShoppingList विधि shoppingList सरणी उनके inShoppingList गुण सेट करने के लिए हाँ आइटम के साथ पॉप्युलेट करता है । buildShoppingList विधि में, हम अस्थाई रूप से शॉपिंग सूची आइटम संग्रह करने के लिए एक परिवर्तनशील सरणी बनाएं । हम तो मदों की सूची के माध्यम से पुनरावृति और परिवर्तनशील सरणी है कि हां के एक inShoppingList संपत्ति है हर आइटम जोड़ें । अंत में, हम अपरिवर्तनीय सरणी की सामग्री के साथ shoppingList संपत्ति सेट ।
शीर्ष पर TSPItem वर्ग के हैडर फ़ाइल आयात करने के लिए मत भूलना ।
#import "TSPItem.h"
हम यह भी ओवरराइड setShoppingList सेटर तालिका दृश्य हर बार पुनः लोड करने के लिए shoppingList सरणी बदल या अद्यतन किया जाता है ।
- (void)setShoppingList:(NSArray *)shoppingList { if (_shoppingList != shoppingList) { _shoppingList = shoppingList; // Reload Table View [self.tableView reloadData]; } }
खरीदारी सूची प्रदर्शित करना
UITableViewDataSource प्रोटोकॉल के तरीकों को लागू करने से अब तक बच्चे का खेल होना चाहिए । नीचे प्रत्येक विधि के कार्यांवयन पर एक नज़र रखना ।
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; }
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.shoppingList count]; }
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // Dequeue Reusable Cell UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; // Fetch Item TSPItem *item = [self.shoppingList objectAtIndex:[indexPath row]]; // Configure Cell [cell.textLabel setText:[item name]]; return cell; }
सेल पुनः प्रयोग पहचानकर्ता को घोषित करने के लिए मत भूलना और हम TSPListViewController वर्ग में किया है जैसे UITableViewCell वर्ग रजिस्टर ।
@implementation TSPShoppingListViewController static NSString *CellIdentifier = @"Cell Identifier";
- (void)viewDidLoad { [super viewDidLoad]; // Register Class for Cell Reuse [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:CellIdentifier]; }
आइटम लोड कर रहा है
जैसा कि मैंने पहले बताया, आइटम की सूची का उपयोग करने की दुकान और खरीदारी की सूची बनाने के प्रमुख लाभ यह है कि आवेदन केवल एक ही स्थान में प्रत्येक आइटम भंडार । यह सूची में और खरीदारी की सूची में एक सिर दर्द के बहुत कम में आइटम अद्यतन करता है । loadItems विधि एक हम TSPListViewController वर्ग में लागू करने के लिए समान है ।
- (void)loadItems { NSString *filePath = [self pathForItems]; if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) { // self.items = [NSMutableArray arrayWithContentsOfFile:filePath]; self.items = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath]; } else { self.items = [NSMutableArray array]; } }
बेशक, pathForItems विधि के रूप में अच्छी तरह से समान है क्योंकि हम TSPListViewController वर्ग के रूप में एक ही फाइल से मदों की सूची लोड कर रहे हैं ।
- (NSString *)pathForItems { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documents = [paths lastObject]; return [documents stringByAppendingPathComponent:@"items.plist"]; }
जब आप अपने आप कोड दोहराव मिल जाए, तुम एक अलार्म घंटी बज सुनना चाहिए । जब आप कोई नई सुविधा कार्यान्वित कर रहे हों, तो कोड को डुप्लिकेट करना समस्याग्रस्त नहीं है । बाद में, हालांकि, आप अनुप्रयोग के कोड आधार में दोहराव की मात्रा को कम करने के लिए अपने कोड refactorिंग पर विचार करना चाहिए । यह सॉफ्टवेयर के विकास में एक बहुत महत्वपूर्ण अवधारणा है और अक्सर के रूप में शुष्क करने के लिए भेजा है, अपने आप को दोहराना नहीं है । क्रिस पीटर्स Tuts पर एक महान लेख + सूखी प्रोग्रामिंग के बारे में लिखा था ।
इससे पहले कि हम TSPShoppingListViewController वर्ग का उपयोग करने के लिए डाल, हम कक्षा के initWithCoder: विधि अद्यतन करने की आवश्यकता है । दृश्य नियंत्रक का शीर्षक सेट करने के अलावा, हम भी आइटम, जो स्वचालित रूप से shoppingList सरणी के रूप में हम पहले देखा आबाद की सूची लोड ।
- (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { // Set Title self.title = @"Shopping List"; // Load Items [self loadItems]; } return self; }
मुख्य स्टोरीबोर्ड अद्यतन कर शॉपिंग सूची दृश्य नियंत्रक को प्रारंभ करने के लिए अंतिम चरण है । इसमें एक UITableViewController इंस्टेंस जोड़ना शामिल है, इसके वर्ग को TSPShoppingListViewController करने के लिए सेटिंग्स, नेविगेशन कंट्रोलर में एम्बेड करना, और टैब बार कंट्रोलर और नेविगेशन कंट्रोलर के बीच संबंध segue बनाना है. नाम segue ShoppingListViewController । शॉपिंग सूची दृश्य नियंत्रक का तालिका दृश्य चुनें और प्रोटोटाइप कक्षों की संख्या को 0 पर सेट करें.



यदि सब कुछ ठीक से काम कर रहा है देखने के लिए अनुप्रयोग चलाएं । बेशक, खरीदारी की सूची वर्तमान में खाली है और हम एक तरह से खरीदारी की सूची में आइटम जोड़ने के लिए नहीं है । चलो अगले कदम में यह उपाय ।
11. शॉपिंग सूची में आइटम जोड़ना
जैसा कि मैंने पहले लिखा था, विचार के लिए खरीदारी की सूची में एक आइटम जोड़ने जब यह सूची दृश्य नियंत्रक में उपयोग है । उपयोगकर्ता अनुभव को बेहतर बनाने के लिए, यदि कोई आइटम शॉपिंग सूची में मौजूद है, तो हम आइटम के नाम के बाईं ओर एक हरी चेकमार्क दिखाते हैं । यदि शॉपिंग सूची में पहले से ही किसी आइटम का उपयोग कर लिया जाता है, तो उसे शॉपिंग सूची से निकाल दिया जाता है और हरी चेकमार्क गायब हो जाती है. इसका मतलब यह है कि हम tableView: didSelectRowAtIndexPath: UITableViewDelegate प्रोटोकॉल की विधि पर एक नज़र लेने की जरूरत है ।
इससे पहले कि हम tableView लागू: didSelectRowAtIndexPath:, इस पाठ के स्रोत फ़ाइलों को डाउनलोड करें । संसाधनों का नाम फ़ोल्डर में, चेकमार्क. png और checkmark@2x.png नाम की फ़ाइलें ढूंढें, और दोनों इन फ़ाइलों को प्रोजेक्ट में जोड़ें । हम कुछ ही क्षणों में उनकी जरूरत होगी ।
tableView की पहली पंक्ति में: didSelectRowAtIndexPath:, हम तालिका दृश्य deselectRowAtIndexPath का एक संदेश: एनिमेटेड: उपयोगकर्ता टैप पंक्ति अचयनित करने के लिए भेजते हैं । जब भी एक पंक्ति उपयोग किया जाता है, यह केवल इसलिए यह इसके अलावा एक पल के लिए प्रकाश डाला जाना चाहिए । अगला, हम चयनित पंक्ति के लिए संबंधित आइटम लाने और आइटम के inShoppingList गुण अद्यतन (हां नहीं हो जाता है और इसके विपरीत) ।
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:YES]; // Fetch Item TSPItem *item = [self.items objectAtIndex:[indexPath row]]; // Update Item [item setInShoppingList:![item inShoppingList]]; // Update Cell UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; if ([item inShoppingList]) { [cell.imageView setImage:[UIImage imageNamed:@"checkmark"]]; } else { [cell.imageView setImage:nil]; } // Save Items [self saveItems]; }
आइटम के setInShoppingList गुण के मान के आधार पर, हम या तो हरी चेकमार्क को दिखाते या छुपाते हैं । हम चेकमार्क को तालिका दृश्य कक्ष के imageView गुण की छवि गुण सेट करके दिखाते हैं । प्रत्येक UITableViewCell आवृत्ति में इसकी बाईं ओर एक छवि दृश्य है (UIImageView वर्ग की एक आवृत्ति). छवि दृश्य की छवि गुण को शूंय पर सेट करके, छवि दृश्य रिक्त है, कोई छवि नहीं दिखा रहा है ।
tableView के कार्यांवयन: didSelectRowAtIndexPath: परिवर्तन स्थाई है यह सुनिश्चित करने के लिए डिस्क के लिए आइटंस की सूची को सहेज कर समाप्त करता है ।
सूची दृश्य नियंत्रक में किसी आइटम को उपयोगकर्ता द्वारा टैप करने पर शॉपिंग सूची कैसे पता होती है? सूची दृश्य नियंत्रक में आइटम्स की सूची में कोई परिवर्तन किया गया था, तो शॉपिंग सूची दृश्य नियंत्रक अपने तालिका दृश्य स्वचालित रूप से अद्यतन नहीं करेगा । इसके अलावा, हम सूची दृश्य नियंत्रक और शॉपिंग सूची दृश्य नियंत्रक तंग युग्मन के किसी भी रूप को रोकने के लिए एक दूसरे से सीधे संवाद करने के लिए नहीं करना चाहती ।
इस समस्या का एक समाधान सूचनाओं का उपयोग है । जब भी सूची दृश्य नियंत्रक आइटम्स की सूची में कोई परिवर्तन करता है, तो यह सूचना केंद्र, सूचनाओं को प्रबंधित करने वाले किसी ऑब्जेक्ट के लिए एक विशिष्ट नाम के साथ एक सूचना पोस्ट करती है. कुछ सूचनाओं में रुचि रखने वाले ऑब्जेक्ट्स स्वयं को उन सूचनाओं के पर्यवेक्षक के रूप में जोड़ सकते हैं, जिसका अर्थ है कि वे सूचनाएँ सूचना केंद्र पर पोस्ट किए जाने पर प्रतिक्रिया दे सकती हैं.
यह सब कैसे काम करता है? तीन चरण हैं:
- शॉपिंग सूची दृश्य नियंत्रक सूचना केंद्र बता रही है कि यह TSPShoppingListDidChangeNotification के एक नाम के साथ सूचनाएं प्राप्त करने में रुचि है द्वारा शुरू होता है
- सूची दृश्य नियंत्रक पोस्ट अधिसूचना केंद्र के लिए एक अधिसूचना जब भी यह मदों की सूची अद्यतन
- जब शॉपिंग सूची दृश्य नियंत्रक सूचना केंद्र से सूचना प्राप्त करता है, तो वह इसके डेटा स्रोत और तालिका दृश्य को प्रत्युत्तर में अद्यतित कर
इससे पहले कि हम तीन कदम मैं सिर्फ वर्णित लागू, यह एक अच्छा विचार है NSNotificationCenter वर्ग में एक करीब देखो ले ।
संक्षेप में, NSNotificationCenter सूचनाओं के प्रसारण का प्रबंधन करता है । किसी अनुप्रयोग में ऑब्जेक्ट addObserver का उपयोग करके सूचना प्राप्त करने के लिए सूचना केंद्र के साथ पंजीकरण कर सकते हैं: चयनकर्ता: नाम: ऑब्जेक्ट: जहां
- पहला तर्क वह वस्तु है, जिसे सूचनाएं प्राप्त होंगी (प्रेक्षक)
- चयनकर्ताओं की यह कार्रवाई है कि प्रेक्षक को सूचना मिलने पर ट्रिगर किया जाएगा
- नाम है अधिसूचना का नाम
- अंतिम तर्क वह ऑब्जेक्ट है जो सूचना भेजता है
यदि अंतिम तर्क शूंय पर सेट है, तो प्रेक्षक को निर्दिष्ट नाम के साथ प्रत्येक सूचनाएं प्राप्त होती हैं ।
सूचनाएं प्राप्त करना
initWithCoder: TSPShoppingListViewController वर्ग की विधि और TSPShoppingListDidChangeNotification का एक नाम के साथ सूचनाएँ प्राप्त करने के लिए एक पर्यवेक्षक के रूप में दृश्य नियंत्रक आवृत्ति जोड़ें ।
- (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { // Set Title self.title = @"Shopping List"; // Add Observer [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateShoppingList:) name:@"TSPShoppingListDidChangeNotification" object:nil]; } return self; }
जब दृश्य नियंत्रक को उस नाम के साथ एक सूचना प्राप्त होती है, तो क्रिया ट्रिगर updateShoppingList: । हम शून्य करने के लिए वस्तु सेट के रूप में यह वास्तव में कोई बात नहीं है जो वस्तु अधिसूचना भेजा.
हम updateShoppingList लागू करने से पहले:, हम खरीदारी सूची दृश्य नियंत्रक की viewDidLoad विधि में संशोधन करने की आवश्यकता है । viewDidLoad में, हम डिस्क से आइटम लोड ।
- (void)viewDidLoad { [super viewDidLoad]; // Load Items [self loadItems]; // Register Class for Cell Reuse [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:CellIdentifier]; }
सूचनाओं का जवाब देना
जब प्रेक्षक को सूचना प्राप्त होती है तो ट्रिगर किया गया तरीका एक विशिष्ट स्वरूप होता है जैसा कि आप नीचे देख सकते हैं । यह एक तर्क स्वीकार करता है, अर्थात, अधिसूचना ऑब्जेक्ट जो NSNotification प्रकार का है । सूचना ऑब्जेक्ट सूचना पोस्ट ऑब्जेक्ट के लिए कोई संदर्भ रखता है और यह भी अतिरिक्त जानकारी के साथ कोई शब्दकोश में हो सकते हैं । UpdateShoppingList:
का कार्यान्वयन विधि काफी सरल है, यानी, loadItems
विधि को व्यू कंट्रोलर पर कॉल किया जाता है, जिसका अर्थ है कि आइटम की सूची डिस्क से लोड की जाती है। बाकी कस्टम सेटर विधियों के लिए स्वचालित रूप से धन्यवाद होता है जिसे हमने पहले लागू किया था।
- (void)updateShoppingList:(NSNotification *)notification { // Load Items [self loadItems]; }
अधिसूचना भेजना
पहेली दृश्य का तीसरा टुकड़ा जब भी सूची दृश्य नियंत्रक द्वारा आइटम की सूची बदल जाती है तो अधिसूचना पोस्ट कर रही है। हम इसे TSPListViewController
क्लास की saveItems
विधि में कर सकते हैं।
- (void)saveItems { NSString *filePath = [self pathForItems]; [NSKeyedArchiver archiveRootObject:self.items toFile:filePath]; // Post Notification [[NSNotificationCenter defaultCenter] postNotificationName:@"TSPShoppingListDidChangeNotification" object:self]; }
पहेली दृश्य का तीसरा टुकड़ा जब भी सूची दृश्य नियंत्रक द्वारा आइटम की सूची बदल जाती है तो अधिसूचना पोस्ट कर रही है। हम इसे TSPListViewController क्लास की saveItems विधि में कर सकते हैं।
प्रोजेक्ट बनाने से पहले, तालिका दृश्य में संशोधन करना सुनिश्चित करें: cellForRowAtIndexPath: जैसा कि खरीदारी सूची में पहले से मौजूद वस्तुओं के लिए एक हरा चेकमार्क प्रदर्शित करने के लिए नीचे दिखाया गया है।
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // Dequeue Reusable Cell UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; // Fetch Item TSPItem *item = [self.items objectAtIndex:[indexPath row]]; // Configure Cell [cell.textLabel setText:[item name]]; [cell setAccessoryType:UITableViewCellAccessoryDetailDisclosureButton]; // Show/Hide Checkmark if ([item inShoppingList]) { [cell.imageView setImage:[UIImage imageNamed:@"checkmark"]]; } else { [cell.imageView setImage:nil]; } return cell; }
इसे एक स्पिन देने के लिए शॉपिंग सूची एप्लिकेशन चलाएं। क्या आपने देखा है कि एक आइटम में संपादन स्वचालित रूप से शॉपिंग सूची में दिखाई देता है?



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