我需要我的UITableViewController来反映数据库的变化,请帮我决定最好的方法并告诉我如何

时间:2014-03-04 14:59:38

标签: ios objective-c cocoa-touch uitableview uitabbarcontroller

以下是展望:

enter image description here

我的根控制器是一个UITabBarController。图像中的数字13是我的默认视图,我设置为在首次打开应用时显示人员列表。

第4页显示我通过单击第3页上的设置链接所采用的页面。在第4页上,我可以通过确认待处理人员或将已确认的人员脱机来管理主视图中的人员。基本上我可以设置是否显示或删除,如果我愿意。

更改始终显示在5和6中,因为我在删除,确认或状态更改后删除了行。在详细视图7中进行编辑时,更改很容易更新,因为我更新了在segue期间传递的Person对象。所以当我回到5中的表视图时,我只是在viewWillLoad方法中使用“self.tableView reloadData”。

在表6中,当我点击一行时弹出操作表,并让我可以选择将任何当前确认的人重新下线。我所做的就是删除行,就是这样。当我返回到控制器视图4然后单击“待定”或“已确认”时,将运行ViewDidLoad。

现在问题

与我在4号中的控制器不同,当我的第一个UITableViewController选项卡被点击或首次加载应用程序时,会显示我的13号主表。我的代码加载到viewDidLoad方法中,因此只加载一次。

这是我的数据显示在主视图上的方式:

- (void)populatePeopleArrayWithCloudData {
    // Grab data and store in Person instances and then store each person in array

    people = [[NSMutableArray alloc] init];

    PFQuery *query = [PFQuery queryWithClassName:@"People"];
    [query whereKey:@"active" equalTo:@1];
    [query orderByDescending:@"createdAt"];
    [query setLimit:10];
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {

        if (!error) {
            for (PFObject *object in objects) {

                Person *person = [[Person alloc] init];
                [person setName:[object objectForKey:@"name"]];
                [person setNotes:[object objectForKey:@"notes"]];
                [person setAge:[[object objectForKey:@"age"] intValue]];
                [person setSince:[object objectForKey:@"since"]];
                [person setFrom:[object objectForKey:@"from"]];
                [person setReferenceNumber:[object objectForKey:@"referenceNumber"]];

                PFFile *userImageFile = object[@"image"];
                [userImageFile getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) {
                    if (!error) {
                        UIImage *image = [UIImage imageWithData:imageData];
                        [person setImage:image];
                    }
                }];

                [person setActive:[[object objectForKey:@"active"] intValue]];
                [person setObjectId:[object objectId]];
                [people addObject:person];
            }

        } else {
            // Log details of the failure
            NSLog(@"Error: %@ %@", error, [error userInfo]);
        }

        NSLog(@"Calling reloadData on %@ in viewDidLoad", self.tableView);
        [self.tableView reloadData]; 
    }];
}

代码从parse中获取数据,运行for循环,将每个人存储在Person实例中,并将其添加到NSMutableArray实例“people”。这个people实例可以通过我的tableview数据源方法访问。

当我点击另一个标签然后再次点击我的主标签时,未再次加载viewDidLoad。好的,这是可以理解的。现在,如果我希望我的主表(13)反映表5和表6中所做的更改,该怎么办?我以为我可以去viewWillAppear并运行“self.tableView reloadData”。我这样做了,什么也没发生。那就是我的想法。经过一番乱搞之后,我意识到我的“人员”数组没有使用我数据库中的最新数据进行更新。

然后我决定尝试从viewWillAppear调用我的populatePeopleArrayWithCloudData方法,但这只会导致重复的条目。我的people数组用于填充表13两次。我说确定让我把populatePeopleArrayWithCloudData方法带出viewDidLoad。这显示了工作和更改,但后来我开始遇到加载图像,显示较晚,最后一行问题等问题。在viewDidLoad中调用populatePeopleArrayWithCloudData方法解决了所有这些问题。

我喜欢在viewDidLoad中使用代码,因为这意味着对数据库的调用较少。就像当用户点击一行并将它们带到详细视图14和15并返回到13时,不会像在代码处于viewWillAppear时那样对数据库进行调用。

所以我想知道解决这个问题的最佳方法是,如何从tableView 6更新“people”实例(一旦“脱机点击”)和tableview 5 (一旦点击“发布”确认某人)。发布用户将活动状态设置为1.状态为1的对象包含在上面的查询结果中,因此显示在主表视图列表中。将某人离线将其活动状态设置为0表示它们不会显示在主列表中。

1。从我的表视图5和6访问“people”实例然后适当更新人员数组是不是很好/正确? 可能在更新后有一个类似于populatePeopleArrayWithCloudData的方法重新填充人。然后在viewWillAppear中我再次重新加载表,希望它检测到新人实例并使用它。

2。如果是这样,我该怎么做?如果可能的话,你能否展示一个明确的例子......

第3。如果没有,你会建议我这样做,你能否展示一个明确的例子。

感谢您的时间 亲切的问候。

1 个答案:

答案 0 :(得分:0)

您可以采取几种方法,但(假设我理解您的问题)我认为最好的方法是拥有一组人的共享实例。你要做的是创建一个名为ManyPeople的NSObject并添加以下内容:

ManyPeople.h:

 @property (nonatomic, strong) NSMutableArray *manyPeople;

 +(ManyPeople *) sharedInstance;

ManyPeople.m

+ (ManyPeople *) sharedInstance
 {
if (!_sharedInstance)
{
    _sharedInstance = [[ManyPeople alloc] init];
}

return _sharedInstance;
}

现在你所有的UIViewControllers都可以调用ManyPeople *people = [ManyPeople sharedInstance];并获得相同的数组。在调用数据库时,您将填充共享实例。更改设置时,还会对共享实例进行更改。美妙之处在于,当您返回到视图控制器13时,您所做的只是reloadData,而您无需拨打数据库。数据源已指向更新的数组。