【问题标题】:Update data source of a parent view controller更新父视图控制器的数据源
【发布时间】:2012-02-03 21:17:01
【问题描述】:

我有三个级别的 ViewController,它们从整体类别向下钻取到该类别中的主题,再到该主题中的引用。

视图控制器被调用:

1   CategoryViewController
2   SubjectViewController
3   QuoteViewController

数据库表“SUBJECT”有类别和主题列。

当我在 SubjectViewController 中时,我可以编辑或删除主题和类别。

我希望能够更新父视图控制器 CategoryViewController 的数据源并“刷新”它的 tableView,所以当我导航回它时,我已经看到显示的表中反映的更改。

解决这个问题的正确方法是什么?

【问题讨论】:

    标签: iphone objective-c ios tableview


    【解决方案1】:

    我认为委托是最适合这项任务的方法。您应该创建一个名为 SubjectViewControllerDelegate 的新协议并添加一些方法,例如:

    - (void)subjectViewController:(SubjectViewController*)controller didEditSubject:(Subject*)subject;
    - (void)subjectViewController:(SubjectViewController*)controller didDeleteSubject:(Subject*)subject;
    

    SubjectViewController 有一个委托属性来保持对其委托的弱引用。 每当删除或编辑数据时,它都会调用委托方法。

    CategoryViewController 实现了这个协议,并将自己设置为 SubjectViewController 实例的委托,然后再将其推送到导航控制器。在这种方法中,您可以刷新所有表,也可以只更新已更改的行。

    更新:

    假设您在 CategoryViewController 中只有一个部分,并将主题保存在 NSMutableArray 中,您可以使用类似于下面的代码来更新表格视图的相关部分。

    - (void)subjectViewController:(SubjectViewController*)controller didEditSubject:(Subject*)subject{
        NSInteger row;
        NSIndexPath* indexPath;
        NSArray* indexPaths;
    
        row = [self.subjects indexOfObject:subject];
        indexPath = [NSIndexPath indexPathForRow:row inSection:0];
        indexPaths = [NSArray arrayWithObject:indexPath];
        [self.tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];    
    }
    
    - (void)subjectViewController:(SubjectViewController*)controller didDeleteSubject:(Subject*)subject{
        NSInteger row;
        NSIndexPath* indexPath;
        NSArray* indexPaths;
    
        row = [self.subjects indexOfObject:subject];
        indexPath = [NSIndexPath indexPathForRow:row inSection:0];
        indexPaths = [NSArray arrayWithObject:indexPath];
        [self.subjects removeObjectAtIndex:row];
        [self.tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
    }
    

    【讨论】:

    • 有趣。我已经有一个 QuotesAppDelegate,我认为它是整体代表。由于我没有跟踪,我需要阅读更多关于代表的信息。我应该为 SubjectViewController 设置一个单独的委托,还是可以使用同一个委托?你能给我一个例子,说明我将如何调用委托并更新更改的行。
    • QuotesAppDelegate 是您的应用程序委托,不应用于此任务。您可以阅读有关委派here 的更多信息。我已经更新了我的答案并添加了一些代码来向您展示如何更新表格视图的更改行。
    【解决方案2】:

    使用UIViewControllers

    @property(nonatomic, readonly) UIViewController *parentViewController
    

    你可以这样做

    CategoryViewController *cvc = (id)self.parentViewController
    if ([cvc isKindOfClass:[CategoryViewController class]]) {
      // call stuff on cvc, like a table view's -reloadData
    }
    

    或者你可以引入一个通知类型并观察它。

    【讨论】:

      【解决方案3】:

      您可以像这样从活动的 ViewController(例如 SubjectViewController)发送一个全局通知:

      [[NSNotificationCenter defaultCenter] postNotificationName:@"refresh_data" object:nil];
      

      然后在你用来刷新的视图控制器中监听它:

      [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dataChanged) name:@refresh_data" object:nil];
      
      - (void)dataChanged {
      // perform the refreshing 
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-08-06
        • 2019-10-04
        • 1970-01-01
        • 1970-01-01
        • 2012-10-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多