UITableview始终为所有单元格加载最后一个对象

时间:2013-09-30 05:50:51

标签: ios objective-c uitableview

我正在尝试从AddressBook中检索所有联系人,并将以下详细信息存储在Mutable数组中。

属性

@property (nonatomic, assign) ABAddressBookRef addressBook;
@property (nonatomic, strong) NSMutableArray *contactList;
@property (nonatomic, strong) IBOutlet UITableView *contactsTableView;

检索所有联系人的方法

- (void)getAllContacts {
    //line moved inside For loop as per Amar's answer. 
    //NSMutableDictionary *personModel = [[NSMutableDictionary alloc]initWithCapacity:0];
    self.addressBook = ABAddressBookCreateWithOptions(NULL, NULL); //iOS 6 and above
    CFArrayRef cList = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(self.addressBook, NULL, kABPersonSortByFirstName);
    CFIndex nPeople = ABAddressBookGetPersonCount(self.addressBook);
    for (int i=0; i<nPeople; i++) {
        //Moving this line here per Amar's answer below. The code works perfectly now.
        NSMutableDictionary *personModel = [[NSMutableDictionary alloc]initWithCapacity:0];
        ABRecordRef personRef = CFArrayGetValueAtIndex(cList, i); // Person will have name, phone number, address, email id and contact image

        //Get the name
        NSString *firstName = (__bridge NSString *)(ABRecordCopyValue(personRef, kABPersonFirstNameProperty));
        NSString *lastName = (__bridge NSString *)(ABRecordCopyValue(personRef, kABPersonLastNameProperty));
        NSString *name = nil;
        if(firstName!=nil && lastName!=nil) { //both names are available
            name = [NSString stringWithFormat:@"%@ %@",firstName,lastName];
        } else if(firstName!=nil && lastName==nil) { //last name not available
            name = [NSString stringWithFormat:@"%@",firstName];
        } else if(firstName==nil && lastName!=nil) { //first name not available
            name = [NSString stringWithFormat:@"%@",lastName];
        } else {
            name = @"Unnamed Contact"; //both names not available
        }
        //Get the phone numbers
        ABMultiValueRef phoneRef = ABRecordCopyValue(personRef, kABPersonPhoneProperty);
        NSMutableArray *phoneNumbers = [NSMutableArray new];
        CFIndex ctr = ABMultiValueGetCount(phoneRef);
        if(ctr!=0) {
            NSString *phoneNumber = nil;
            for (CFIndex i=0; i<ctr; i++) {
                phoneNumber = (__bridge NSString *) ABMultiValueCopyValueAtIndex(phoneRef, i);
                [phoneNumbers addObject:phoneNumber];
            }
        } else {
            [phoneNumbers addObject:@"Phone not available"];
        }

        //Get the contact address
        ABMultiValueRef addrRef = ABRecordCopyValue(personRef, kABPersonAddressProperty);
        NSMutableArray *addresses = [NSMutableArray new];
        ctr = ABMultiValueGetCount(addrRef);
        if(ABMultiValueGetCount(addrRef)!=0) {
            for(CFIndex i=0; i<ABMultiValueGetCount(addrRef); i++) {
                CFDictionaryRef addr = ABMultiValueCopyValueAtIndex(addrRef, i);
                NSString *street = (__bridge NSString *)CFDictionaryGetValue(addr, kABPersonAddressStreetKey);
                NSString *city = (__bridge NSString *)CFDictionaryGetValue(addr, kABPersonAddressCityKey);
                NSString *state = (__bridge NSString *)CFDictionaryGetValue(addr, kABPersonAddressStateKey);
                NSString *zip = (__bridge NSString *)CFDictionaryGetValue(addr, kABPersonAddressZIPKey);
                NSString *address = [NSString stringWithFormat:@"%@, %@, %@ %@",street,city,state,zip];
                [addresses addObject:address];
            }
        } else {
            [addresses addObject:@"Address not available"];
        }

        //Get the email address
        ABMultiValueRef emailRef = ABRecordCopyValue(personRef, kABPersonEmailProperty);
        NSMutableArray *emailAddresses = [NSMutableArray new];
        ctr = ABMultiValueGetCount(emailRef);
        if(ctr!=0) {
            for(CFIndex i=0; i<ctr; i++) {
                NSString *eId = (__bridge NSString*)ABMultiValueCopyValueAtIndex(emailRef, i);
                [emailAddresses addObject:eId];
            }
        } else {
            [emailAddresses addObject:@"EmailID not available"];
        }

        //Get the contact image
        UIImage *image = nil;
        if(ABPersonHasImageData(personRef)) image = (__bridge UIImage *)(ABPersonCopyImageDataWithFormat(personRef, kABPersonImageFormatThumbnail));

        //Append the values to a dictionary
        [personModel setValue:name forKey:@"cName"];
        [personModel setValue:phoneNumbers forKey:@"cPhone"];
        [personModel setValue:addresses forKey:@"cAddresses"];
        [personModel setValue:emailAddresses forKey:@"cEmailID"];
        [personModel setValue:image forKey:@"cImage"];

        [self.contactList addObject: personModel];
    }
}

在tableView的数据源方法cellForRowAtIndexPath

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ContactsCell forIndexPath:indexPath];

    cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:16];
    cell.textLabel.textColor = [UIColor blackColor];
    cell.detailTextLabel.font = [UIFont systemFontOfSize:14.0];
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    NSDictionary *model = [self.contactList objectAtIndex:indexPath.row];
    NSLog(@"Name:%@",[model valueForKey:@"cName"]);
    cell.textLabel.text =[model valueForKey:@"cName"];
    return cell;
}

我的地址簿中有四个联系人。但是,我的tableView始终返回最后一个联系人的姓名(这是“未命名联系人”,因为它没有名/姓)。

Unnamed Contact
Unnamed Contact
Unnamed Contact
Unnamed Contact

知道为什么吗?

2 个答案:

答案 0 :(得分:2)

那是因为这一行

NSMutableDictionary *personModel = [[NSMutableDictionary alloc]initWithCapacity:0];

for - 循环之外。在迭代联系人列表并修改相同的字典之前,您只需创建一次字典。因此,它将始终存储最后的联系信息。

相反,在for循环中移动上面的代码行,它将创建一个新的字典,用于在列表中存储每个联系人。

希望有所帮助!

答案 1 :(得分:0)

  

每次将数据存储在具有相同KEY'cName'的字典中时   [personModel setValue:name forKey:@“cName”];“这就是为什么每一次   使用相同的密钥覆盖值,最后一条记录存储在   这就是问题产生的原因,你需要存储你的数据   用不同的键或直接从数组获取数据而不是   字典