如果使用 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
【问题讨论】:
仅供参考-您的代码效率极低。numberOfRowsInSection
和 cellForRowAtIndexPath
将被调用很多次。你不断地对键进行排序。对它们进行一次排序并保留参考。
我实际上对此有点陌生。因此,我从教程中获得了代码,但它使用的是 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 则一切正常
如果我使用 SharedPreferences,使用 onSaveInstanceState 是不是有用
如果可以使用 synchronized(this),为啥还要使用 ReentrantLock?