如果使用 commitEdittingStyle 为空,则删除 tableview 行和部分

Posted

技术标签:

【中文标题】如果使用 commitEdittingStyle 为空,则删除 tableview 行和部分【英文标题】:Deleting tableview row and section if empty with commitEdittingStyle 【发布时间】:2014-11-04 00:31:45 【问题描述】:

我似乎找不到太多关于此的内容。我目前正在尝试创建一个可滑动的删除按钮,该按钮将删除被滑动的行,如果该行现在从节标题中为空,它也会删除节标题。比如“面包”是刷删的,“B”这个节头下就没有别的了。然后这将删除面包和“B”部分标题。我的代码如下。

@interface ChoicesTableViewController () <UITableViewDelegate, UITableViewDataSource>
@property (weak, nonatomic) IBOutlet UITableView *myTableView;
@property (strong, nonatomic) NSMutableArray *items;
@property (strong, nonatomic) NSMutableDictionary *alphabetizedItems;

@end

@implementation ChoicesTableViewController

- (id)initWithStyle:(UITableViewStyle)style

    self = [super initWithStyle:style];
    if (self) 
        // Custom initialization
    
    return self;


- (void)viewDidLoad

    [super viewDidLoad];
    self.myTableView.delegate = self;
    self.myTableView.dataSource = self;

    self.items = [[NSMutableArray alloc] init];
    [self.items addObject:@"Apples"];
    [self.items addObject:@"Bread"];
    self.alphabetizedItems = [self alphabetizeItems:self.items];


//Segue if the item is tapped
//- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
//
//    MyDataChoices *currentRow = self.arrayNames[indexPath.row];
//    self.mySelectedCell = currentRow.myNameChoices;
//    
//    [self performSegueWithIdentifier:@"unwindSegueAction" sender:self];
//    
//
////unwind segue from add choice
- (IBAction)unwindSegueToChoices:(UIStoryboardSegue *)segue


    AddChoiceViewController *sourceVC = segue.sourceViewController;
    NSString *myNewItem = sourceVC.myTextField.text;
    //NSString *myFinalString = [[myNewItem substringToIndex:1] capitalizedString];
    NSString *stringCapitalized = [myNewItem capitalizedString];
    [self.items addObject:stringCapitalized];
    self.alphabetizedItems = [self alphabetizeItems:self.items];
    //[self.arrayNames addObjectsFromArray:@[[MyDataChoices itemWithNewName:stringCapitalized]]];
    [self.tableView reloadData];


//titles for talble view
#pragma mark Helper Methods
- (NSMutableDictionary *)alphabetizeItems:(NSArray *)items 
    NSMutableDictionary *buffer = [[NSMutableDictionary alloc] init];

    // Put Fruits in Sections
    for (int i = 0; i < [items count]; i++) 
        NSString *fruit = [items objectAtIndex:i];
        NSString *firstLetter = [[fruit substringToIndex:1] uppercaseString];

        if ([buffer objectForKey:firstLetter]) 
            [(NSMutableArray *)[buffer objectForKey:firstLetter] addObject:fruit];

         else 
            NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithObjects:fruit, nil];
            [buffer setObject:mutableArray forKey:firstLetter];
        
    

    // Sort Fruits
    NSArray *keys = [buffer allKeys];
    for (int j = 0; j < [keys count]; j++) 
        NSString *key = [keys objectAtIndex:j];
        [(NSMutableArray *)[buffer objectForKey:key] sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
    

    NSMutableDictionary *result = [NSMutableDictionary dictionaryWithDictionary:buffer];
    return result;

#pragma mark title indexing

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section

    NSArray *keys = [[self.alphabetizedItems allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
    NSString *key = [keys objectAtIndex:section];
    return key;




# pragma mark main table view
-(NSInteger) numberOfSectionsInTableView:(UITableView *) tableView

    NSArray *keys = [self.alphabetizedItems allKeys];
    return [keys count];



-(NSInteger) tableView:(UITableView *) tableView numberOfRowsInSection:(NSInteger)section

    //return self.arrayNames.count;
    NSArray *unsortedKeys = [self.alphabetizedItems allKeys];
    NSArray *sortedKeys = [unsortedKeys sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
    NSString *key = [sortedKeys objectAtIndex:section];
    NSArray *fruitsForSection = [self.alphabetizedItems objectForKey:key];
    return [fruitsForSection count];


-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    //MyDataChoices *currentRow = self.arrayNames[indexPath.row];
    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"mainCell2" forIndexPath:indexPath];

    //cell.textLabel.text = currentRow.myNameChoices;
    NSArray *unsortedKeys = [self.alphabetizedItems allKeys];
    NSArray *sortedKeys = [unsortedKeys sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
    NSString *key = [sortedKeys objectAtIndex:[indexPath section]];
    NSArray *fruitsForSection = [self.alphabetizedItems objectForKey:key];
    NSString *fruit = [fruitsForSection objectAtIndex:[indexPath row]];

    [cell.textLabel setText:fruit];

    return cell;



# pragma Mark delete slide button

//Delete Swipe Button
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath

    // Return NO if you do not want the specified item to be editable.
    return YES;




// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath

    if (editingStyle == UITableViewCellEditingStyleDelete) 
        // Delete the row from the data source
        int index = indexPath.row;
        //[self.items removeObjectAtIndex:index];
        [self.alphabetizedItems removeObjectForKey:indexPath];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
     else if (editingStyle == UITableViewCellEditingStyleInsert) 
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    


- (void)didReceiveMemoryWarning

    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.



@end

【问题讨论】:

仅供参考-您的代码效率极低。 numberOfRowsInSectioncellForRowAtIndexPath 将被调用很多次。你不断地对键进行排序。对它们进行一次排序并保留参考。 我实际上对此有点陌生。因此,我从教程中获得了代码,但它使用的是 NSArrays 和 NSDictionaries。我想因为它们不是可变的,所以这不是一个大问题。我试图理解你是如何说我应该解决这个问题的。我基本上只是为 fruitsForSection 创建一个属性 NSArray 并在 viewdidload 中执行 4 行,而在 numberOfRowsInSection 内部确实返回 [self.fruitsForSection count];? 没有必要像你一样一遍又一遍地对数据进行排序。首次填充 self.alphabetizedItems 时对其进行排序。将排序后的键保存在另一个实例变量中。 明白,感谢您的帮助。 【参考方案1】:

基本方法是查看要删除的行的部分中有多少行。如果该部分有两行或更多行,只需像现在一样删除该行。如果该部分只有一行(被删除的那一行),则从数据模型中删除该部分,然后从表中删除该部分,而不是删除该行。

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath

    if (editingStyle == UITableViewCellEditingStyleDelete) 
        NSArray *unsortedKeys = [self.alphabetizedItems allKeys];
        NSArray *sortedKeys = [unsortedKeys sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
        NSString *key = [sortedKeys objectAtIndex:[indexPath section]];
        NSArray *fruitsForSection = [self.alphabetizedItems objectForKey:key];
        if (fruitsForSection.count == 1) 
            // Delete the whole section
            [self.alphabetizedItems removeObjectForKey:key];
            [tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationFade];
         else 
            // Delete the row from the data source
            NSInteger index = indexPath.row;
            //[self.items removeObjectAtIndex:index];
            [self.alphabetizedItems removeObjectForKey:indexPath];
            [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
        
     else if (editingStyle == UITableViewCellEditingStyleInsert) 
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    

【讨论】:

真的很有帮助。非常感谢。

以上是关于如果使用 commitEdittingStyle 为空,则删除 tableview 行和部分的主要内容,如果未能解决你的问题,请参考以下文章

webView.loadRequest 错误,如果使用 presentViewController,但如果使用 segue 则一切正常

如果上游启动,Nginx 绕过缓存,如果关闭则使用缓存

如果我使用 SharedPreferences,使用 onSaveInstanceState 是不是有用

如果可以使用 synchronized(this),为啥还要使用 ReentrantLock?

SQL Select:如果存在则更新,如果不存在则插入 - 使用日期部分比较?

如何使用ID检查记录,如果记录存在则更新如果不添加新记录