对于这个话题,我的最后一篇文章已经确定了......我尽可能地缩小了它的范围,但我肯定需要帮助才能解决这个问题。 由于我使用的是自定义单元格和嵌入式表视图,因此当键盘出现时我必须自己滚动并隐藏一些文本字段(每个单元格都有一个文本字段)。这很好用。但是,如果我的表视图向上移动,有些单元格隐藏在我的标题后面或导航控制器栏后面,一旦我结束编辑模式,一切都会搞砸。之前隐藏的单元格立即处于正常状态而不是缩进。这看起来很讨厌,我不知道如何解决它。如果没有隐藏细胞,当然一切都很好。
所以我查看了文档并找到了prepareForReuse,我想这可能会有所帮助。不知道怎么解决这个问题?如果有人能给我必要的暗示,我会非常感激...
我有一个只有这种方法的自定义UITableViewCell:
- (void) setEditing:(BOOL)editing animated:(BOOL)animated{
[super setEditing:editing animated:animated];
if (editing){
self.title.hidden = NO;
self.titleLabel.hidden = YES;
self.iconButton.hidden = NO;
self.icon.hidden = YES;
self.costs.hidden = YES;
self.disclosureIndicator.hidden = YES;
self.subcategories.hidden = YES;
} else if (!editing){
self.title.hidden = YES;
self.titleLabel.text = self.title.text;
self.titleLabel.hidden = NO;
self.iconButton.hidden = YES;
self.icon.hidden = NO;
self.subcategories.hidden = NO;
self.costs.hidden = NO;
self.disclosureIndicator.hidden = NO;
}
}
在此初始化并重复使用:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Data model and cell setup
static NSString *CellIdentifier = @"MainCategoryCell";
MainCategoryTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
MainCategory *mainCategory = [self.fetchedResultsController objectAtIndexPath:indexPath];
...
return cell;
}
由于我使用嵌入式表视图,因此我必须自己滚动隐藏的文本字段:
- (void)registerForKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
//Has to be unregistered always, otherwise nav controllers down the line will call this method
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)keyboardWasShown:(NSNotification*)aNotification
{
//All table views are embedded in the parent view
//The parent view y is defined by the status and navigation bar, the height by the tab bar
CGRect viewRect = self.view.frame;
CGRect tableRect = self.tableView.frame;
//The keyboard size will be adjusted that the height is really only the height overlapping the table
NSDictionary* info = [aNotification userInfo];
CGSize kbOriginalSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGFloat effectiveKeyBoardHeight = kbOriginalSize.height - TABBARHEIGHT - (viewRect.size.height - tableRect.size.height - tableRect.origin.y); //the last origin property is important to find out if there is a header
CGSize kbSize = CGSizeMake(kbOriginalSize.width, effectiveKeyBoardHeight);
//Now the content insets will be adjusted for the calculated part of the keyboard overlapping the table
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
self.tableView.contentInset = contentInsets;
self.tableView.scrollIndicatorInsets = contentInsets;
// If active text field is hidden by keyboard, scroll it so it's visible
// I've changed the apple code here! They use viewRect..in my app this doesn't make any sense, tableRect is key
tableRect.size.height -= kbSize.height;
if (!CGRectContainsPoint(tableRect, self.activeField.frame.origin) ) {
[self.tableView scrollRectToVisible:self.activeField.frame animated:YES];
}
}
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
self.tableView.contentInset = contentInsets;
self.tableView.scrollIndicatorInsets = contentInsets;
}
答案 0 :(得分:1)
我认为问题可能是tableview的设置contentInset不会调用tableView的prepareForReuse方法或任何其他方法来调用cellForRow,这会导致隐藏的单元格出现奇怪状态。所以在键盘隐藏方法中,配置所有可能显示单元格状态,然后reloadData将有助于正确显示单元格。
答案 1 :(得分:0)
如果你只是做一个reloadData,我觉得应该清理一切。 (请记住,您的dataSource应保留每个单元格的所有状态。)
答案 2 :(得分:0)
解决了......我一周都在努力解决这个问题,解决方案就是移动一行代码......:
我的开始和结束编辑表:
- (IBAction) editTable:(id)sender
{
if(self.editing)
{
//Change to editing no
[super setEditing:NO animated:YES];
//resigns first responder for all textfields
[self.view endEditing:YES];
[self setEditing:NO animated:YES];
[self.tableView setEditing:NO animated:YES];
//Remove Done button and exchange it with edit button
[self.navigationItem.rightBarButtonItem setTitle:NSLocalizedString(@"Edit", nil)];
[self.navigationItem.rightBarButtonItem setStyle:UIBarButtonItemStylePlain];
self.navigationItem.leftBarButtonItem = nil;
[self.navigationItem setHidesBackButton:NO animated:YES];
[((AppDelegate *)[[UIApplication sharedApplication] delegate]) saveContext];
self.suspendAutomaticTrackingOfChangesInManagedObjectContext = NO;
} else {
//Change to editing mode
[super setEditing:YES animated:YES];
[self.tableView setEditing:YES animated:YES];
[self setEditing:YES animated:YES];
//Exchange the edit button with done button
[self.navigationItem.rightBarButtonItem setTitle:NSLocalizedString(@"Done", nil)];
[self.navigationItem.rightBarButtonItem setStyle:UIBarButtonItemStyleDone];
[self.navigationItem setHidesBackButton:YES animated:YES];
//And insert instead of the back button an add button
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addButtonAction:)];
[self.navigationItem setLeftBarButtonItem:addButton];
}
}
这里的关键是:
[self.tableView setEditing:NO animated:YES];
在结束编辑状态的最底部!之前我在所有细胞的辞职响应者面前,这是错误。因为结束所有单元格的第一响应者的结束编辑当然触发了我的keyboardWillBeHidden方法。然后表格识别它需要两个新单元格,但是如果表格已经结束编辑状态,则单元格处于非编辑状态。但是,如果我将这行代码切换到最后,那么一切都应该正常运行!希望这将在未来的某个时候帮助别人。