2

我有一个 UITableView ,用户在其中单击附件。附件在模态视图中启动 UIView(使用presentViewController)。

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

目前我正在使用单例来捕获字典中的 userData;但即使我使用 NSNotification 我也有同样的问题。

我的问题是,当模式对话框被关闭时,表格视图永远不会更新;但是,如果我滚动或以其他方式物理移动,则表格单元格中的条目将更新。

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

我想知道我是否可以得到一些帮助;如何使单元格重新加载?

与单元格显示相关的代码以及模态的呈现方式如下;

笔记;

_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我在方法内启动我的 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仍然没有刷新它的数据;我仍然需要物理移动表格才能更新单元格。

我该怎么做才能强制单元格正确更新?

4

2 回答 2

0

问题是您在– reloadRowsAtIndexPaths:withRowAnimation:呈现视图控制器(导航)时正在调用。当操作系统完成显示视图控制器时(不是当视图返回时,如您所说),“完成”块被执行,因此对用户可见。

– reloadRowsAtIndexPaths:withRowAnimation:关闭视图控制器时尝试调用。这可能会进入“完成”块– dismissViewControllerAnimated:completion:

希望这可以帮助!

更新:

嗨开衫;我已经看到您更新的问题,让我告诉您,如果在updateTable解除控制器后正确调用该方法,EventNameVC则意味着问题出在其他地方。调用reloadData您的表视图将导致它使用您对基础数据源所做的任何更改来刷新其内容,除非......数据源在您调用时尚未更新reloadData

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

dict = [_template objectAtIndex:indexPath.row];
name = [dict objectForKey:@"name"];

信息来自_template数组。现在,在您的模态视图中,您拥有textName我假设您希望最终在表格视图中显示的属性,对吗?当视图控制器被关闭时,您使用通知在字典中发送该信息,但是当您收到该通知时,我在您的块中看不到您将该信息添加到_template数组的任何地方。你如何更新你的数据源?

也请尝试以下方法:

在方法中添加断点updateTable。当应用程序停止时,添加另一个断点,但这次是在– tableView:cellForRowAtIndexPath:方法中;这将显示该reloadData方法是否正常工作。如果应用程序随后停止,– tableView:cellForRowAtIndexPath:那么您就在正确的道路上。此时继续查看数据源的内容。您可以通过po _template直接在 XCode 控制台中键入(然后按 Enter)来执行此操作。这样,您将能够查看它是否已使用您想要的信息进行了更新。

让我知道事情的后续。

于 2013-09-09T21:32:08.880 回答
0

我接受了@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 现在正在更新,我无需滚动任何内容。

这可能只是一些愚蠢的错误,但我很高兴现在它已经解决了。

感谢大家的帮助!

于 2013-09-11T05:29:01.070 回答