在一个具有 2 个数据源的 TableView 中选择不同的单元格

Selecting Different Cells in One TableView with 2 Data sources

提问人:user717452 提问时间:8/13/2022 更新时间:9/30/2022 访问量:36

问:

在一个视图控制器上,我的顶部有一个 single 和一个。表视图是从 NSArray 填充的,NSArray 通过几种不同的方式之一收集文件。0 段从 2 个文件夹中提取所有 PDF。1段从一个文件夹中提取所有PDF,其中文件名的结尾包含“Kids.pdf”。我试图做的是允许用户创建他们喜欢的歌曲列表并保存它。当段被更改时,我成功地显示了我想要的内容,但问题是复选标记仍然处于打开状态。因此,如果我从第一个段中选择第一行,当我转到另一个段时,它仍然显示该行也已选择。我怎样才能解决这个问题,以便在每个区段之间来回切换将保留用户实际选择的复选标记?UITableViewUISegmentedControl

- (void)viewWillAppear:(BOOL)animated {
    
   
    self.title = @"Choose YourSongs";
    if (filterSongs.selectedSegmentIndex == 0) {
    NSBundle *bundle = [NSBundle mainBundle];
    
    self.files  = [bundle pathsForResourcesOfType:@"pdf" inDirectory:@"thepdfpowerpoints"];
    NSString *documentsDirectoryPath = [self.files objectAtIndex:thepath.row];
    self.filenames = [[documentsDirectoryPath lastPathComponent] stringByDeletingPathExtension];
    
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
       NSString *documentsDirectory = [paths objectAtIndex:0];
    NSArray *thefirstNewArray = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectory error:NULL];
    NSArray *theNewArray = [thefirstNewArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self ENDSWITH '.pdf'"]];

   
    NSMutableArray *names = [NSMutableArray arrayWithCapacity:[self.files count] + [theNewArray count]];
    for (NSString *path in self.files) {
        [names addObject:[[path lastPathComponent] stringByDeletingPathExtension]];
    }
    for (NSString *pathagain in theNewArray) {
        [names addObject:[[pathagain lastPathComponent] stringByDeletingPathExtension]];
    }
    //self.files = names;
    self.files = [names sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
    NSLog(@"FILESLOAD%@", self.files);

     self.tableView.delegate = self;
       self.tableView.dataSource = self;
    }
    else {
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
           NSString *documentsDirectory = [paths objectAtIndex:0];
        NSArray *thefirstNewArray = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectory error:NULL];
        NSArray *theNewArray = [thefirstNewArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self ENDSWITH 'Kids.pdf'"]];

       
        NSMutableArray *names = [NSMutableArray arrayWithCapacity:[theNewArray count]];
        for (NSString *path in self.files) {
            [names addObject:[[path lastPathComponent] stringByDeletingPathExtension]];
        }
        for (NSString *pathagain in theNewArray) {
            [names addObject:[[pathagain lastPathComponent] stringByDeletingPathExtension]];
        }
        //self.files = names;
        self.files = [names sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
        NSLog(@"FILESLOAD%@", self.files);

         self.tableView.delegate = self;
           self.tableView.dataSource = self;
    }
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        NSString *selectedCountry = [self.files objectAtIndex:indexPath.row];
    
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
       NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *pdfPath = [[documentsDirectory stringByAppendingPathComponent:selectedCountry] stringByAppendingString:@".pdf"];
    if  ([[NSFileManager defaultManager] fileExistsAtPath: pdfPath]) {
        //NSLog(@"%@", selectedCountry);
        UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
        
        NSString *addThis = [[pdfPath lastPathComponent] stringByDeletingPathExtension];
        NSLog(@"%@", addThis);
      
        values[indexPath.row] = !values[indexPath.row];
        if (self.chosen == nil) {
            self.chosen = [[NSMutableArray alloc] init];
        }
        if (values[indexPath.row]) {
            newCell.accessoryType = UITableViewCellAccessoryCheckmark;
            [self.chosen addObject:addThis];

        } else {
            newCell.accessoryType = UITableViewCellAccessoryNone;
            [self.chosen removeObject:addThis];

        }
    }
    
    
    else {
    
    
        NSString *Documents = [[NSBundle mainBundle] pathForResource:selectedCountry ofType:@"pdf" inDirectory:@"thepdfpowerpoints"];
        //NSLog(@"%@", selectedCountry);
        UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
        
        NSString *addThis = [[Documents lastPathComponent] stringByDeletingPathExtension];
        NSLog(@"%@", addThis);
      
        values[indexPath.row] = !values[indexPath.row];
        if (self.chosen == nil) {
            self.chosen = [[NSMutableArray alloc] init];
        }
        if (values[indexPath.row]) {
            newCell.accessoryType = UITableViewCellAccessoryCheckmark;
            [self.chosen addObject:addThis];

        } else {
            newCell.accessoryType = UITableViewCellAccessoryNone;
            [self.chosen removeObject:addThis];

        }
    }
        [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
       
    
}

最后是段的代码。

-(IBAction) changeSegment {
    

    if (filterSongs.selectedSegmentIndex == 0) {
    NSBundle *bundle = [NSBundle mainBundle];
    
    self.files  = [bundle pathsForResourcesOfType:@"pdf" inDirectory:@"thepdfpowerpoints"];
    NSString *documentsDirectoryPath = [self.files objectAtIndex:thepath.row];
    self.filenames = [[documentsDirectoryPath lastPathComponent] stringByDeletingPathExtension];
    
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
       NSString *documentsDirectory = [paths objectAtIndex:0];
    NSArray *thefirstNewArray = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectory error:NULL];
    NSArray *theNewArray = [thefirstNewArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self ENDSWITH '.pdf'"]];

   
    NSMutableArray *names = [NSMutableArray arrayWithCapacity:[self.files count] + [theNewArray count]];
    for (NSString *path in self.files) {
        [names addObject:[[path lastPathComponent] stringByDeletingPathExtension]];
    }
    for (NSString *pathagain in theNewArray) {
        [names addObject:[[pathagain lastPathComponent] stringByDeletingPathExtension]];
    }
    //self.files = names;
    self.files = [names sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

     self.tableView.delegate = self;
       self.tableView.dataSource = self;
        [self.tableView reloadData];

    }
    else {
        self.files = nil;
        NSArray *paths2 = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
           NSString *documentsDirectory2 = [paths2 objectAtIndex:0];
        NSArray *thefirstNewArray2 = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectory2 error:NULL];
        NSArray *theNewArray2 = [thefirstNewArray2 filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self ENDSWITH 'Kids.pdf'"]];
        NSLog(@"Kids newArray %@", thefirstNewArray2);
       
        NSMutableArray *names2 = [NSMutableArray arrayWithCapacity:[theNewArray2 count]];
       
        for (NSString *pathagain2 in theNewArray2) {
            [names2 addObject:[[pathagain2 lastPathComponent] stringByDeletingPathExtension]];
        }
        //self.files = names;
        self.files = [names2 sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

         self.tableView.delegate = self;
           self.tableView.dataSource = self;
        [self.tableView reloadData];
    }
 
}
iOS Objective-C Xcode UITableView UIStuageedControl

评论

0赞 Paulw11 8/13/2022
您需要重新考虑您的数据模型。因为你有一个选定的索引路径数组和一个单独的数据项数组,所以在保持这些内容同步时会遇到问题;您只知道选择了哪一行,而不知道选择了哪个数据项。我将创建一个表示每个项目的对象。此对象应具有您需要的任何属性(名称等)以及 a 和一些唯一标识符。将所有项目加载到一个数组中,一次,分配类别和唯一 ID。现在,根据所选类别创建一个过滤后的数组。将其用于表视图。category
0赞 Paulw11 8/13/2022
切换段时,请重新筛选数组并重新加载表视图。若要存储选择状态,请创建并存储所选项目的唯一标识符,而不是索引路径。在检查项目是否在集合中,以确定是否应显示复选标记。NSMutableSetcellForRowAt

答:

1赞 arturdev 9/30/2022 #1

这很简单。当您更改区段选择(更改数据源)时,复选标记的单元格将被重用,因此它会显示具有最新状态的单元格。您需要重置 cellForRowAtIndexPath 方法中的所有状态:

 (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
     //...
      if (values[indexPath.row]) {
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
        } else {
            cell.accessoryType = UITableViewCellAccessoryNone;
        }
     return cell;
 }

一般来说,请记住。如果你在单元格中有一个,你也应该有一个案例,否则你会遇到重用问题。ifelse