iosobjective-cuitableviewabpeoplepickerview

Reload UITableView after ABPeoplePicker selection


So, i have a UITableView loaded in a UIViewController. The table get its data from NSMutableArray

I have added a UIBarButtonItem on the NavigationBar which will open a ABPeoplePickerNavigationController to select a contact and add its name in the NSMutableArray to be displayed in the UITableView

This a summary of my code

@interface LockedChatsTableView : UIViewController <UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate, ABPeoplePickerNavigationControllerDelegate>
@property (strong, nonatomic, retain) UITableView *tabView;
@property (strong, nonatomic) NSMutableArray *listArray;
@end


@implementation LockedChatsTableView

- (void)viewDidLoad {

    UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(showPicker:)];
    self.navigationItem.rightBarButtonItem = addButton;
    self.navigationItem.title = @"Locked Chats";

    [self.listArray removeAllObjects];

    [self.view setBackgroundColor:[UIColor whiteColor]];
    CGFloat width = [UIScreen mainScreen].bounds.size.width;
    CGFloat height = [UIScreen mainScreen].bounds.size.height;
    self.tabView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
    self.tabView.alwaysBounceVertical = NO;
    self.tabView.delegate = self;
    self.tabView.dataSource = self;

    self.listArray = [[NSMutableArray alloc] init];

    NSMutableDictionary *data = [[NSMutableDictionary alloc] initWithContentsOfFile:[self path]];
    self.listArray = [data objectForKey:@"LockedChats"];
    [self.view addSubview:self.tabView];
}

// .... some tableview delegate method ....


-(void)addChatWithName:(NSString *)chatName {
    NSMutableDictionary *data = [[NSMutableDictionary alloc] initWithContentsOfFile:[self path]];
    NSMutableArray *lockedChats = [data objectForKey:@"LockedChats"];

    [lockedChats addObject:chatName];
    [data setObject:lockedChats forKey:@"LockedChats"];
    [data writeToFile:[self path] atomically:YES];       
}

-(void)removeChatWithName:(NSString *)chatName {
    NSMutableDictionary *data = [[NSMutableDictionary alloc] initWithContentsOfFile:[self path]];
    NSMutableArray *lockedChats = [data objectForKey:@"LockedChats"];

    [lockedChats removeObject:chatName];

    [data setObject:lockedChats forKey:@"LockedChats"];
    [data writeToFile:[self path] atomically:YES];
}


// ====================== Contact Picker ======================== //

- (void)showPicker:(UIBarButtonItem *)sender {
    ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];
    picker.peoplePickerDelegate = self;

    [self presentViewController:picker animated:YES completion:nil];
}

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person {

    NSString* name = (__bridge NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty);
    NSString* lastname = (__bridge NSString*)ABRecordCopyValue(person, kABPersonLastNameProperty);

    [self addChatWithName:[NSString stringWithFormat:@"%@ %@",name,lastname]];

    [self dismissViewControllerAnimated:YES completion:nil];

   // [self.tabView performSelectorOnMainThread:@selector(reloadData) withObject:nil];
   // [self.tabView reloadData]; 
    return NO;
}

// .... some other people picker delegate method ....

@end

So my issue is that when i pick a contact and save its name to array, the UITableView is not reloading! I have tried literally every single solution arround:

I am out of idea and been working on this little issue whole day! Your help is much much appreciated.


Solution

  • To update a table, you need to, in this order:

    1. Update your data source (self.listArray) with the new info
    2. Call reloadData on the table, on the main thread

    Your calls to reloadData aren't working because addChatWithName: and removeChatWithName: are only writing to the file; they aren't updating self.listArray. So when you call reloadData, there's no new data to show.


    A few other minor issues, unrelated to your question:

    @property (strong, nonatomic, retain) UITableView *tabView;
    

    You should delete retain (it means the same thing as strong, and it's redundant). Also, I wouldn't call this tabView because future readers might think it's a UITabBar.

    [self.listArray removeAllObjects];
    

    You can delete this line. self.listArray isn't even initialized yet, so this does nothing.