我有一个UITableView,用户可以在其中单击附件。 配件在模式视图中启动 UIView(使用 presentViewController
)。
当它返回时,它意味着使用所需的数据更新表视图单元格。
目前,我正在使用单例来捕获字典中的用户数据;但即使我使用NSNotization,我也有同样的问题。
我的问题是,当模式对话框被关闭时,表视图永远不会更新;但是 如果我滚动或以其他方式物理移动,那么表格中的条目就会更新。
如果我尝试使用 NSNotification 强制重新加载单元格或整个表视图,我会得到相同的结果。
我想知道我是否可以在这方面得到一些帮助; 如何使细胞重新加载?
与单元格显示以及如何显示模态相关的代码如下;
笔记;
_eventName is just a NSString
-(void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if ( [[MySingleton sharedInstance].userData objectForKey:@"eventName"] !=nil) {
_eventName = [[MySingleton sharedInstance].userData objectForKey:@"eventName"];
}
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
NSDictionary *dict;
NSString *name;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
dict = [_template objectAtIndex:indexPath.row];
name = [dict objectForKey:@"name"];
cell.textLabel.text = name;
NSString *key = [[dict objectForKey:@"key"] lowercaseString];
if ([[key lowercaseString] isEqualToString:@"name"]==YES) {
cell.detailTextLabel.text = _eventName;
}
return cell;
}
-(void) tableView:(UITableView *)tv accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *dict = [_template objectAtIndex:indexPath.row];
NSString *key = [[dict objectForKey:@"key"] lowercaseString];
NSString *name = @"";
if ([key isEqualToString:@"name"]==YES) {
EventNameVC *nameEditor = [[EventNameVC alloc] initWithNibName:@"EventNameVC" bundle:nil];
if (_eventName !=nil) {
nameEditor.txtName.text = _eventName;
} else {
nameEditor.txtName.text = name;
}
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:nameEditor];
// When we return from the view, reload the cell.
[self presentViewController:nav animated:YES completion:^{
[self.tv reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight];
}];
nav = nil;
}
}
编辑:尝试使用通知来检测模态的关闭; 但我仍然有同样的问题 - 也就是说,UITableView仅在我物理移动表时显示更新的数据。
在我的视图控制器中,我这样做;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
self.notificationObserver = [[NSNotificationCenter defaultCenter]
addObserverForName:@"dismissModalView"
object:nil
queue:mainQueue
usingBlock:^(NSNotification *notification) {
NSLog(@"Notification received!");
NSDictionary *userInfo = notification.userInfo;
_eventName = [userInfo objectForKey:@"eventName"];
NSLog(@"received._eventName = %@", _eventName);
[self performSelectorOnMainThread:@selector(updateTable) withObject:nil waitUntilDone:YES];
}];
}
return self;
}
-(void) updateTable {
NSLog(@"%s", __PRETTY_FUNCTION__);
[self.tv reloadData];
}
我在accessoryButtonTappedForRowWithIndexPath
方法中启动我的模态视图
EventNameVC *nameEditor = [[EventNameVC alloc] initWithNibName:@"EventNameVC" bundle:nil];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:nameEditor];
[self presentViewController:nav animated:YES completion:nil];
好的,因此,当我们使用 presentViewController
和 Departure 启动模态视图时,将触发通知。
在我的模态视图中
-(IBAction) btnSave:(id)sender {
[self.txtName resignFirstResponder];
///[[MySingleton sharedInstance].userData setObject:self.txtName.text forKey:@"eventName"];
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:self.txtName.text forKey:@"eventName"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"dismissModalView" object:self userInfo:userInfo];
[self dismissViewControllerAnimated:YES completion:nil];
}
当我运行它时,updateTable 被正确触发并记录在控制台中。
目前为止,一切都好。
但是表视图仍然没有刷新其数据;我仍然需要物理移动表格才能更新单元格。
我该怎么做才能强制单元格正确更新?
问题是您在呈现视图控制器 (nav) 时调用– reloadRowsAtIndexPaths:withRowAnimation:
。"完成"块在操作系统显示完视图控制器时执行(而不是像您所说的那样,当视图返回时),因此对用户可见。
尝试在关闭视图控制器时调用– reloadRowsAtIndexPaths:withRowAnimation:
。这可能进入– dismissViewControllerAnimated:completion:
的"完成"块
希望这有帮助!
更新:
嗨,卡迪根;我已经看到了您更新的问题,让我告诉您,如果在EventNameVC
控制器被解雇后正确调用updateTable
方法,则意味着问题出在其他地方。在表视图上调用 reloadData
将导致它使用您对基础数据源所做的任何更改刷新其内容,除非...在您调用 reloadData
时,数据源尚未更新。
通过查看您的– tableView:cellForRowAtIndexPath:
方法,我可以看到您从以下两行代码中获取单元格的信息:
dict = [_template objectAtIndex:indexPath.row];
name = [dict objectForKey:@"name"];
信息来自_template
数组。现在,在您的模态视图中,您拥有 textName
属性,我假设该属性是您最终要在表视图中显示的内容,对吗?当视图控制器被关闭时,您使用通知将该信息发送到字典中,但是当您收到该通知时,我在您的块中看不到将该信息添加到_template
数组的任何地方。如何更新数据源?
请同时尝试以下操作:
向updateTable
方法添加断点。当应用程序停止时,添加另一个断点,但这次是– tableView:cellForRowAtIndexPath:
方法;这将向您显示reloadData
方法是否正常工作。如果应用程序随后停止– tableView:cellForRowAtIndexPath:
那么您的路径是正确的。此时,继续查看数据源的内容。您可以通过直接在 XCode 控制台上键入 po _template
(然后按回车键)来执行此操作。这样,您就可以查看它是否已使用所需的信息进行更新。
让我知道它是怎么回事。
我接受了@LuisCein的回答。 我重写了我的表视图。 它现在正在更新;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
self.pTemplate = [[MySingleton sharedInstance] pTemplate];
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
[[NSNotificationCenter defaultCenter]
addObserverForName:@"dismissModalView"
object:nil
queue:mainQueue
usingBlock:^(NSNotification *notification) {
NSLog(@"Notification received!");
NSDictionary *userInfo = notification.userInfo;
_eventName = [userInfo objectForKey:@"eventName"];
NSLog(@"received._eventName = %@", _eventName);
[self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES];
}];
}
return self;
}
...
- (NSInteger)tableView:(UITableView *)tv numberOfRowsInSection:(NSInteger)section
{
return pTemplate.count;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
NSDictionary *dict = [self.pTemplate objectAtIndex:indexPath.row];
NSString *name = [dict objectForKey:@"name"];
cell.textLabel.text = name;
cell.detailTextLabel.text = @"Detail text";
NSString *key = [[dict objectForKey:@"key"] lowercaseString];
if ([[key lowercaseString] isEqualToString:@"name"]==YES) {
if (_eventName !=nil) cell.detailTextLabel.text = _eventName;
}
if ([[key lowercaseString] isEqualToString:@"date"]==YES) {
NSString *dateString = [dateFormater stringFromDate:_eventDate];
if (_eventDate !=nil) cell.detailTextLabel.text = [NSString stringWithFormat:@"%@", dateString];
}
if ([[key lowercaseString] isEqualToString:@"venue"]==YES) {
if (_venueName != nil) cell.detailTextLabel.text = _venueName;
}
cell.detailTextLabel.textColor = [UIColor darkGrayColor];
return cell;
}
-(void) tableView:(UITableView *)tv accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *dict = [self.pTemplate objectAtIndex:indexPath.row];
NSString *key = [[dict objectForKey:@"key"] lowercaseString];
if ([key isEqualToString:@"name"]==YES) {
if (_eventName !=nil) {
[[MySingleton sharedInstance].userData setObject:_eventName forKey:@"eventName"];
}
EventNameVC *nameEditor = [[EventNameVC alloc] initWithNibName:@"EventNameVC" bundle:nil];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:nameEditor];
[self presentViewController:nav animated:YES completion:nil];
nav = nil;
}
if ([key isEqualToString:@"date"]==YES) {
}
if ([key isEqualToString:@"venue"]==YES) {
}
}
这段代码正确显示我的 uitableview 和单元格,我转到视图,对文本进行更改并提交 nsnotification。
-(IBAction) btnSave:(id)sender {
[self.txtName resignFirstResponder];
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:self.txtName.text forKey:@"eventName"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"dismissModalView" object:self userInfo:userInfo];
[self dismissViewControllerAnimated:YES completion:nil];
}
现在一切似乎都正常了。 uitableview现在正在更新,而无需我滚动任何内容。
这可能只是一些愚蠢的错误,但我很高兴现在它解决了。
感谢大家的帮助!