Objective c 仅在移动表格时刷新UITableView才有效?

Objective c 仅在移动表格时刷新UITableView才有效?,objective-c,uitableview,reloaddata,Objective C,Uitableview,Reloaddata,我有一个用户点击附件的UITableView。附件在模式视图中启动UIView(使用presentViewController) 当它返回时,意味着用所需的数据更新tableview单元格 目前,我正在使用单例来捕获字典中的用户数据;但即使我使用NSN通知,我也有同样的问题 我的问题是,当模式对话框被取消时,tableview永远不会更新;然而 如果我滚动或以其他方式移动表格,则单元格中的条目将更新 如果我尝试使用NSNotifications强制重新加载单元格或整个tableview,则会得到

我有一个用户点击附件的UITableView。附件在模式视图中启动UIView(使用
presentViewController

当它返回时,意味着用所需的数据更新tableview单元格

目前,我正在使用单例来捕获字典中的用户数据;但即使我使用NSN通知,我也有同样的问题

我的问题是,当模式对话框被取消时,tableview永远不会更新;然而 如果我滚动或以其他方式移动表格,则单元格中的条目将更新

如果我尝试使用NSNotifications强制重新加载单元格或整个tableview,则会得到相同的结果

我想知道我是否能在这方面得到一些帮助;如何重新加载单元格

与单元显示和模式显示方式相关的代码如下所示

注释

\u eventName只是一个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
方法中启动我的modalView

EventNameVC *nameEditor = [[EventNameVC alloc] initWithNibName:@"EventNameVC" bundle:nil];
        UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:nameEditor];
        [self presentViewController:nav animated:YES completion:nil];
好的,所以当我们使用
presentViewController
启动模态视图时,在撤销时,会触发通知

在我看来

-(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被正确触发并记录在控制台中

到目前为止还不错

但是tableview仍然没有刷新它的数据;我仍然需要移动表格来更新单元格


如何强制单元格正确更新?

问题在于,当您显示视图控制器(nav)时,您正在调用
–reloadRowsAtIndexPaths:withRowAnimation:
。“completion”块在操作系统完成显示视图控制器时执行(而不是在您所说的视图返回时),因此用户可见

关闭视图控制器时,尝试调用
–reloadRowsAtIndexPaths:withRowAnimation:
。这可能会出现在
–dismissViewControllerAnimated:completion:

希望这有帮助

更新:

Hi羊毛衫;我已经看到了您更新的问题,让我告诉您,如果在取消
EventNameVC
控制器后正确调用了
updateTable
方法,则表示问题出在其他地方。在表视图上调用
reloadData
,将导致它使用您对基础数据源所做的任何更改刷新其内容,除非。。。调用
reloadData
时,数据源尚未更新

通过查看您的
–tableView:cellForRowAtIndexPath:
方法,我可以看到您可以从以下两行代码中获得单元格的信息:

dict = [_template objectAtIndex:indexPath.row];
name = [dict objectForKey:@"name"];
信息来自
\u模板
数组。现在,在模态视图中,您有
textName
属性,我假设它是您希望最终在表视图中显示的,对吗?当视图控制器被解除时,您使用通知在字典中发送该信息,但当您收到该通知时,我看不到您在块中的任何地方将该信息添加到
\u模板
数组中。如何更新数据源

还请尝试以下操作:

updateTable
方法添加断点。当应用程序停止时,添加另一个断点,但这次添加到
–tableView:cellforrowatinexpath:
方法;这将显示
reloadData
方法是否正常工作。如果应用程序随后停止在
–tableView:cellForRowAtIndexPath:
中,则您的路径是正确的。此时,继续查看数据源的内容。您可以通过直接在XCode控制台中键入
po\u template
(然后按enter键)来完成此操作。这样,您就可以查看是否已使用所需信息对其进行了更新


告诉我进展如何。

我接受了@luiscin的回答。我重新编写了我的tableview。目前正在更新

- (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和单元格,我转到视图,对文本进行更改并提交通知

-(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现在正在更新,无需滚动任何内容

这可能只是一个愚蠢的错误,但我很高兴现在问题解决了


谢谢大家的帮助

尝试在表视图上调用
reloadData
,以强制其刷新。当您说将reloadData放在tableView上时,使用哪种方法?你的意思是在
[self-presentViewController:nav-animated:YES completion…
的完成块中还是其他地方?我曾尝试将重新加载的数据放入
视图中,使其看起来像
[self.tv reloadData]这不会导致单元格正确显示。愚蠢的问题:当调用reloadData时,
self.tv
是否指向正确的表视图?是的。但我会尝试重写整个视图,以防我犯了愚蠢的错误。好吧,我会试试这个。我一直在试图找出哪里出错,所以这可能会对sol有所帮助我在那里。我曾尝试使用NSNotification重新加载整个表。它侦听模式解雇。通知可以工作;但在我实际移动tableview之前,表仍然无法正确显示。您在回答中提到,我可以在
dismissViewControllerAnimated
中使用
重新加载行…
>但我不知道该怎么做。好的,我会试试。非常感谢,我感谢你的帮助。我已经完全重写了我的uitableview,去掉了所有的垃圾并使它变得简单,出于某种原因,它现在正在工作。我将接受你的回答,因为我不确定我做了什么来修复它