Я хочу использовать ABPeoplePickerNavigationController
, но хочу настроить представление. Я хочу, чтобы у некоторых контактов было вспомогательное изображение, и я хочу отсортировать их иначе, чем по умолчанию. Есть ли способ сделать это? Или мне нужно создать свой собственный UITableViewController
?
Настройка ABPeoplePickerNavigationController
Ответы (1)
Вам придется создать собственное табличное представление, если вы хотите настроить внешний вид контактов таким образом. Например, вы можете извлечь контакты, используя:
- (void)loadContacts
{
ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();
if (status == kABAuthorizationStatusDenied) {
// if you got here, user had previously denied/revoked permission for your
// app to access the contacts, and all you can do is handle this gracefully,
// perhaps telling the user that they have to go to settings to grant access
// to contacts
[[[UIAlertView alloc] initWithTitle:nil message:@"This app requires access to your contacts to function properly. Please visit to the \"Privacy\" section in the iPhone Settings app." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
return;
}
CFErrorRef error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
if (error) {
NSLog(@"ABAddressBookCreateWithOptions error: %@", CFBridgingRelease(error));
if (addressBook) CFRelease(addressBook);
return;
}
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
if (error) {
NSLog(@"ABAddressBookRequestAccessWithCompletion error: %@", CFBridgingRelease(error));
}
dispatch_async(dispatch_get_main_queue(), ^{
if (granted) {
// if they gave you permission, then get copy of contacts and reload table
self.allContacts = CFBridgingRelease(ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, NULL, kABPersonSortByLastName));
[self.tableView reloadData];
} else {
// however, if they didn't give you permission, handle it gracefully, for example...
[[[UIAlertView alloc] initWithTitle:nil message:@"This app requires access to your contacts to function properly. Please visit to the \"Privacy\" section in the iPhone Settings app." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
}
if (addressBook) CFRelease(addressBook);
});
});
}
И затем вы можете использовать этот массив в своем cellForRowAtIndexPath
:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
ABRecordRef person = (__bridge ABRecordRef)self.allContacts[indexPath.row];
NSMutableArray *nameArray = [NSMutableArray array];
NSString *prefix = CFBridgingRelease(ABRecordCopyValue(person, kABPersonPrefixProperty));
if (prefix) [nameArray addObject:prefix];
NSString *firstName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty));
if (firstName) [nameArray addObject:firstName];
NSString *middleName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonMiddleNameProperty));
if (middleName) [nameArray addObject:middleName];
NSString *lastName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonLastNameProperty));
if (lastName) [nameArray addObject:lastName];
NSString *fullname = [nameArray componentsJoinedByString:@" "];
NSString *suffix = CFBridgingRelease(ABRecordCopyValue(person, kABPersonSuffixProperty));
if (suffix) {
fullname = [NSString stringWithFormat:@"%@, %@", fullname, suffix];
}
cell.textLabel.text = fullname;
NSString *company = CFBridgingRelease(ABRecordCopyValue(person, kABPersonOrganizationProperty));
if ([fullname length] == 0) {
cell.textLabel.text = company;
cell.detailTextLabel.text = nil;
} else {
cell.detailTextLabel.text = company;
}
if ([nameArray count] == 0 && [company length] == 0)
NSLog(@"nothing to show!!!");
return cell;
}
Очевидно, учитывая, что вся идея заключалась в том, что вы хотели настроить ячейку, соответствующим образом измените cellForRowAtIndexPath
, но, надеюсь, это иллюстрирует идею.
person
Rob
schedule
14.08.2014
При использовании этого кода я получаю, что некоторые из моих контактов вижу дважды. Я заметил, что у некоторых из этих контактов есть FaceTime. Как я могу настроить, чтобы каждый контакт отображался только один раз?
- person bobsacameno; 17.08.2014
Я только что понял, что контакты, дважды появляющиеся на моем столе, являются результатом того, что они являются контактами на iPhone и в iCloud. Есть ли способ заставить их появляться только один раз?
- person bobsacameno; 18.08.2014
Несколько вариантов: 1. Вы можете перечислить источники, а затем позволить пользователю выбрать источник, а затем получить все контакты для этого источника. 2. Вы можете вручную найти и удалить дубликаты (но когда вы найдете дубликат, я не уверен, как вы определите, какой из них победит, если есть незначительные различия). 3. Вы можете объединить свои контакты iCloud с контактами iPhone, чтобы у вас был только один источник.
- person Rob; 18.08.2014
1. Как указать, какой источник использовать, и какое правильное имя для источника
iPhone
и источника iCloud
? 2. Вручную означает, что мне нужно просмотреть каждый контакт и сравнить его со всеми остальными контактами, верно? Нет более простого способа сделать это. 3. объединение контактов означает, что пользователь должен сделать это на самом iPhone. Или слияние — это то, что приложение может делать только для self.allContacts
, которое вы определили в ответе? (и поэтому это будет что-то вроде решения 2).
- person bobsacameno; 18.08.2014
1. Вы должны использовать что-то вроде
ABAddressBookCopyArrayOfAllSources
для получения массива источников. 2. Да, вручную означает повторение контактов самостоятельно, хотя, если они отсортированы, вы, вероятно, можете просто сравнить их с предыдущей записью, а не сравнивать их со всеми другими контактами. 3. Да, я имел в виду, что если ваши контакты (или любой пользователь) случайно продублировались в двух разных источниках, вы сами пройдете этот процесс на своем iPhone. С точки зрения жизнеспособности iPhone наличие ненужных дубликатов в разных источниках — настоящая проблема (легко забыть, над каким из них вы работаете).
- person Rob; 18.08.2014
UITableViewController
- person Mohit   schedule 14.08.2014You should not need to subclass these controllers; the expected way to modify their behavior is by your implementation of their delegate
это то, что говорится в документе Apple. developer.apple.com/library/ios/documentation/ContactData/ - person Mohit   schedule 14.08.2014ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, nil); self.allContacts = (__bridge NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBookRef);
Это работает для меня, но когда я отображаю этот массив вUITableViewController
, он выглядит не отсортированным. Ты знаешь почему? Я думал, что он вернет массив, отсортированный по алфавиту имен контактов. - person bobsacameno   schedule 14.08.2014__bridge_transfer
(илиCFBridgingRelease
), а не__bridge
, иначе ваше приложение будет просачиваться. Во-вторых, вы можете сортировать, если используетеABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering
. Или просто отсортируйте массив самостоятельно, используя одну из многочисленных процедур сортировки, напримерsortedArrayUsingComparator
. - person Rob   schedule 14.08.2014