2016-08-11 172 views
0

我已阅读每篇文章并多次尝试所有解决方案,但无法获得正确的功能。保存,保留和检索数组中的选定单元格

我有一个来自本地JSON文件的数据的tableview。我需要的用户能够:

  1. 选择多个单元格
  2. 显示复选标记上选定单元格
  3. 写那些选择到一个数组
  4. 删除选择时选中

5.当用户切换查看或离开并返回到tableview,关闭并重新打开应用程序等时,用选中标记保存/保留选项。

我已经设法得到1-4的工作,但我被困在#5,无法想象出我的生活。我尽可能地尝试了NSUserDefaults。任何帮助表示赞赏。以下是当前的代码。

此外,为什么我不得不双击一个单元格取消选中它?

@interface FilterViewController() <UISearchResultsUpdating> 

@property (nonatomic, strong) NSArray *IngredientsArray; 
@property (nonatomic, strong) UISearchController *searchController; 
@property (nonatomic, strong) NSMutableArray *searchResults; 
@property (nonatomic, strong) NSMutableArray *selectedCell; 
@property (nonatomic, strong) NSMutableArray *selectedIngredients; 
//I added this property to keep track of the selected row 
@property (strong,nonatomic) NSIndexPath *selectedPath; 


@end 

@implementation FilterViewController { 
    NSArray *_locations; 


} 


- (void)viewDidLoad { 


    [super viewDidLoad]; 

    self.selectedIngredients = [NSMutableArray array]; 
    self.selectedCell = [NSMutableArray array]; 
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
    self.lastIndexPath = [defaults objectForKey:@"lastIndexPathUsed"]; 



    // Create a new JSONLoader with a local file URL 
    JSONLoaderIngreds *jsonLoader = [[JSONLoaderIngreds alloc] init]; 
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"locations" withExtension:@"json"]; 

    // There's no transition in our storyboard to our search results tableview or navigation controller 
    // so we'll have to grab it using the instantiateViewControllerWithIdentifier: method 
    UINavigationController *searchResultsController = [[self storyboard] instantiateViewControllerWithIdentifier:@"FilterViewSearchResultsNavController"]; 

    // Our instance of UISearchController will use searchResults 
    self.searchController = [[UISearchController alloc] initWithSearchResultsController:searchResultsController]; 

    // The searchcontroller's searchResultsUpdater property will contain our tableView. 
    self.searchController.searchResultsUpdater = self; 


    // create the searchBar programatically. 
    self.searchController.searchBar.frame = CGRectMake(self.searchController.searchBar.frame.origin.x, 
                 self.searchController.searchBar.frame.origin.y, 
                 self.searchController.searchBar.frame.size.width, 44.0); 

    self.tableView.tableHeaderView = self.searchController.searchBar; 


    //Sets LocationsViewController as presenter for LocationDetailViewController after searxh results dsiplayed 
    //and selected.. Required so searchbar doesn't show in detailsview after segue, and instead, default nav 
    //controller back button displays. 
    self.definesPresentationContext = true; 





    // Load the data on a background queue... 
    // As we are using a local file it's not really necessary, but if we were connecting to an online URL then we'd need it 
    //NSString *ingreds = [dict objectForKey:@"ingredients"] 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     _locations = [jsonLoader ingredientsFromJSONFile:url]; 
     // Now that we have the data, reload the table data on the main UI thread 
     [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES]; 

     }); 

} 

// Just before showing the LocationViewController, set the selected Location object 
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
    LocationsViewController *vc = segue.destinationViewController; 
    NSIndexPath *indexPath = [self.tableView indexPathForCell:sender]; 
    vc.location = [_locations objectAtIndex:indexPath.row]; 

} 

- (void)didReceiveMemoryWarning { 
    [super didReceiveMemoryWarning]; 
} 

- (void)viewWillAppear:(BOOL)animated 
{ 
    //I added this if clause to select the row that was last selected 
    if (self.selectedPath != nil) { 
     [self.tableView selectRowAtIndexPath:self.selectedPath animated:NO scrollPosition:UITableViewScrollPositionNone]; 
    } 

} 

#pragma mark - Table View Controller Methods 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 

    self.selectedPath = indexPath; 
    NSString *Ingredient = [_locations objectAtIndex:indexPath.row]; 
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 
    if([self isRowSelectedOnTableView:tableView atIndexPath:indexPath]){ 
     [self.selectedCell removeObject:indexPath]; 
     [self.selectedIngredients removeObject:Ingredient]; 
     cell.accessoryType = UITableViewCellAccessoryNone; 
    } else { 
     [self.selectedCell addObject:indexPath]; 
     [self.selectedIngredients addObject:Ingredient]; 
     cell.accessoryType = UITableViewCellAccessoryCheckmark; 
    } 
    NSLog(@"***************Selected Ingredients**************** %@", self.selectedIngredients); 
    NSUserDefaults *userdefaults = [NSUserDefaults standardUserDefaults]; 
    [userdefaults setObject:[NSString stringWithFormat:@"%ld",(long)indexPath.section] forKey:@"lastIndexPathUsed"]; 
    [userdefaults synchronize]; 


} 

-(BOOL)isRowSelectedOnTableView:(UITableView *)tableView atIndexPath:(NSIndexPath *)indexPath 
{ 
    return ([self.selectedCell containsObject:indexPath]) ? YES : NO; 
} 



- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    static NSString *unifiedID = @"FilterCell"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:unifiedID]; 

    if (!cell) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:unifiedID]; 
    } 

    cell.textLabel.text = [_locations objectAtIndex:indexPath.row]; 
    cell.imageView.image = [UIImage imageNamed:@"ingredientsicon3232.png"]; 

    //if the indexPath was found among the selected ones, set the checkmark on the cell 
    cell.accessoryType = ([self isRowSelectedOnTableView:tableView atIndexPath:indexPath]) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone; 
    return cell; 


} 



- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    return [_locations count]; 
} 

UPDATE:

我设法改变的代码的建议使用下面的更新的代码,以节省选择以阵列NSUserDefaults,但我仍然无法弄清楚,以节省所需的cellForRowAtIndexPath代码/记住检查标记。

我该如何编码cellForRowAtIndexPath来调用复选标记?

保存的选择要与此代码数组:

的viewDidLoad代码:

_selections = [NSMutableArray arrayWithArray:(NSArray *)[[NSUserDefaults standardUserDefaults] objectForKey:@"selections"]]; 
    if(_selections == nil){ 
     _selections = [[NSMutableArray alloc] init]; 
    } 

didSelectRowAtIndexPath方法代码:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 

    { 
    if ([_selections containsObject: cell.textLabel.text] == NO){ 
     [_selections addObject:cell.textLabel.text]; 
     cell.accessoryType = UITableViewCellAccessoryCheckmark; 
    } else { 
     [_selections removeObject:cell.textLabel.text]; 
     cell.accessoryType = UITableViewCellAccessoryNone; 
    } 
    NSLog(@"***************Selected Ingredients**************** %@", _selections); 
    NSUserDefaults *userdefaults = [NSUserDefaults standardUserDefaults]; 

    [userdefaults setObject:_selections forKey:@"selections"]; 
    [userdefaults synchronize]; 
    NSLog(@"-------------NSUserDefaults------------%@", [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]) 

} 

回答

0

你的解决方案是非常简单的。

  1. 首先,您需要将选定索引路径的数组保存到您的用户默认对象而不是最后选定的路径。
  2. 每当用户选择或取消选择一行时。从同一个阵列添加和删除对象并将其保存回用户默认值。
  3. 在您的cellForRowAtIndexPath中,检查您的索引路径是否存在保存在用户默认值中的数组中。如果存在,请选中带有复选标记的行,否则保持原样。

希望这会有所帮助。

+0

我想我明白了,但是您能否展示如何在代码中完成这项工作?我尝试过几种不同的方式,无法工作。仍在学习。谢谢。 – Jason

+0

我正在旅行。可能在几个小时内,我可以给你一个例子,但现在你应该尝试这三个步骤,你会得到它。这并不困难。只要给它一个。 – Harsh

+0

按照你的指示,我已经设法将选择保存到用户默认值存储的数组中,但我无法弄清楚保留选中标记的代码。你能提供代码示例吗? – Jason

0

我想,而不是与那些indexPath工作,我建议你与数据本身直接运行,加Bool属性,以表明您Ingredient类的选择,那么整个数组保存CoreData/Realm/NSUserDefault,这种方式更准确因为您的数据可能会发生变化,导致您保存的选择indexPath可能不再正确