2016-08-11 360 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可能不再正確