gpt4 book ai didi

ios - 需要创建一个像ABPeoplePickerNavigationController这样的自定义 View

转载 作者:行者123 更新时间:2023-12-01 18:53:00 25 4
gpt4 key购买 nike

我想创建一个自定义视图,就像iPhone中的联系人一样。是否有任何教程可以像ABPeoplePickerNavigationController一样制作自定义视图?

请注意,我不想打开AddressBookUI框架提供的默认人员选择器控制器。另外,我确实想将此导航控制器绑定到我的主视图中。

对于我真正想要的参考,您可以在iOS设备上参考Whatsapp的联系人选项卡。

编辑:我已经有一个联系人列表,并在表视图中显示了人的名字和姓氏。现在,我想为A-Z中的字母创建索引,并在点击该索引时,表格视图应滚动到该联系人。另外,如何实现搜索功能以按用户的名字或姓氏查找用户?

最佳答案

我正在开发的应用程序中有完全相同的东西,当涉及到联系人时,我们还从类似Whatsapp的应用程序中获得了灵感。

我使用带有自定义单元格的简单表格视图进行视觉处理,仅使用名称和图片。

我的过程如下:

  • 在coredata中创建contact对象(或另一种持久保存数据的方式)
  • 通过ABAddressbook框架,您可以浏览所有联系人并将其转换为新的Contact objets。在ABPerson对象中保留对Contact的引用,这将使您以后仅使用引用即可查找和更新联系人。如果不这样做,则每次要更新联系人时都必须浏览至所有ABPerson。
    您可以直接使用ABPerson,但是编写代码确实很痛苦。
  • 提取所有联系人后,如果使用核心数据,请确保保存上下文,或将其存储在.sqlite中。
  • 然后,您可以简单地将它们提取到一系列联系人中,并将其显示在您选择的自定义单元格中。

  • This appcoda tutorial是用于tableview教程的一个不错的自定义单元格。您可以通过谷歌搜索“tableview自定义单元ios”并找到您可能喜欢的不同东西来找到上千个。最后,您将只有一个带有标签和图片的单元格,您可以使用简单的 UITableViewCell,我将其用于另一种“联系人”类型的表格视图。

    使该联系人列表保持最新状态(获取正确的电话号码,图片,姓名等),并确保它们在更新之前存在,检查联系人是否已被删除,添加等。准确地说,这是一个相当漫长/烦人的过程。

    我可以共享我的Contact类,但其中包含许多与您无关的代码,这可能会使您感到困惑,因为:
    -我还在检查那些联系人是否已经是我的应用程序的用户,以便将它们移到表视图的特定部分
    -我将表格视图分为27个部分(用户,然后是字母)。

    另外,我将用最后的一般编程建议来停止它:一个好主意是首先准确地写下您需要的东西和需要的东西,将所有可能性写在纸上,等等。我花了一些时间解决了很多简单的问题,要么是因为我没有正确计划,要么是因为它被隐藏了。

    例如 :
  • 您的某些联系人根本没有名字。
  • 您的某些联系人在“标题”字段(您在其中编写Doctor或Mister)中具有名称。
  • 您的某些联系人没有电话号码(如果您使用电话号码作为标识符)
  • 您的某些联系人具有国际格式,而有些则没有(+32 46556555或0032 46556555)
  • 您的某些联系人使用相机拍摄的照片,其他一些来自Gmail的照片则使用不同的格式
  • 由于用户
  • 同步不佳,您可能有重复的联系人(同名,所有内容均相同)
  • 您需要确保名字/姓氏在正确的部分,区分大小写的编码可能会引起麻烦
  • 您需要找到以笑脸或非字母数字字符开头的联系人的解决方案
  • 您的用户需要在
  • 侧面有一个索引列表
  • 当然,您需要添加搜索栏,因为有些人拥有1000多个联系人。
  • 我保证,还有更多。

  • 因为这是非常特定于应用程序的,所以我不会解决我遇到的每个问题以及我为此所做的事情,但是您会明白的:)尽管可以提出任何非常具体的问题,但是我可能已经有一个非常具体的问题解决方案,因为我几乎不得不从头开始复制whatsapp的联系人, hell ,我做到了。 (我实际上与Anonymess和iOS完全相同)

    编辑:这是我的ABPerson提取方法的一些方法; ContactDAO主要与我的持久性模型(CoreData)交互,我相信它们的名称足够清晰,可以让您了解正在发生的事情。我对注释和变量名感到满意,因此您应该阅读它而不会遇到太多麻烦。

    这里有大量的代码块。
    - (NSMutableArray *)getAllRecordsWithPeople:(CFArrayRef)allPeople andAddressBook:(ABAddressBookRef)addressbook{
    NSMutableArray *newRecords = [[NSMutableArray alloc]init];
    CFIndex nPeople = ABAddressBookGetPersonCount(addressbook);

    for (int i=0;i < nPeople;i++){

    ABRecordRef ref = CFArrayGetValueAtIndex(allPeople,i);
    ABRecordID refId = ABRecordGetRecordID(ref);
    NSNumber *recId = [NSNumber numberWithInt:refId];
    [newRecords addObject:recId];
    }

    return newRecords;
    }

    - (void)getValidContactsFromAddressBookWithCompletionBlock:(void (^)(NSError *error))completion{

    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, nil);

    __block BOOL accessGranted = NO;

    if (&ABAddressBookRequestAccessWithCompletion != NULL) {
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

    ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
    accessGranted = granted;
    dispatch_semaphore_signal(semaphore);
    });

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    }

    if (accessGranted) {

    NSMutableArray *newRecords = [[NSMutableArray alloc]init];
    NSMutableArray *updatedRecords = [[NSMutableArray alloc]init];
    NSMutableArray *unchangedRecords = [[NSMutableArray alloc]init];

    CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
    CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);

    //Checking the last time we updated
    NSTimeInterval lastSyncTime;
    if ([[NSUserDefaults standardUserDefaults]objectForKey:@"LastSyncTime"] == nil){
    //This is the first time we update.
    lastSyncTime = 0;
    }else{
    //Setting the last update in variable
    lastSyncTime = [[[NSUserDefaults standardUserDefaults]objectForKey:@"LastSyncTime"]doubleValue];
    }

    if (lastSyncTime == 0){
    //We have to insert everyone, this is the first time we do this.
    newRecords = [self getAllRecordsWithPeople:allPeople andAddressBook:addressBook];
    }else{
    //We have to manually compare everyone to see if something has changed.

    for (int i=0;i < nPeople;i++) {

    ABRecordRef ref = CFArrayGetValueAtIndex(allPeople,i);
    ABRecordID refId = ABRecordGetRecordID(ref);
    NSNumber *recId = @(refId);

    CFDateRef recordCreation = ABRecordCopyValue(ref, kABPersonCreationDateProperty);
    NSDate *recCreDate = (__bridge NSDate *)(recordCreation);
    NSTimeInterval creDateInterval = [recCreDate timeIntervalSince1970];

    if(creDateInterval > lastSyncTime){
    //This object was created after my lastSync, this must be a new record
    [newRecords addObject:recId];

    }else{

    //Checking the last update of the given record
    CFDateRef recordUpdate = ABRecordCopyValue(ref, kABPersonModificationDateProperty);
    NSDate *recUpDate = (__bridge NSDate*)(recordUpdate);

    if ([recUpDate timeIntervalSince1970] > lastSyncTime){
    //The record was somehow updated since last time, we'll update it
    [updatedRecords addObject:recId];

    }else{
    //The record wasn't updated nor created, it is therefore unchanged.
    //We still need to keep it in a separate array to compare deleted contacts
    [unchangedRecords addObject:recId];
    }
    }

    }
    if(allPeople)
    CFRelease(allPeople);
    }

    [self manageNewContacts:newRecords updatedContacts:updatedRecords andUnchangedContacts:unchangedRecords inAddressBook:addressBook andBlock:^(NSError *error) {
    completion(error);
    }];
    }else{
    NSError *error = [NSError errorWithDomain:@"ABAccess access forbidden" code:403 userInfo:nil];
    completion(error);
    }
    }

    - (void)manageNewContacts:(NSMutableArray*)newRecords updatedContacts:(NSMutableArray*)updatedRecords andUnchangedContacts:(NSMutableArray*)unchangedRecords inAddressBook:(ABAddressBookRef)addressbook andBlock:(void (^)(NSError *error))completion{

    AppDelegate *app = [UIApplication sharedApplication].delegate;
    NSManagedObjectContext *context = app.managedObjectContext;

    //Getting all the CoreData contacts IDs to have something to compare
    NSArray *coreDataContactsIds = [ContactDAO getAllContactIdsInManagedObjectContext:context];

    for (NSDictionary *rec in coreDataContactsIds){
    NSNumber *recId = rec[@"record_id"];
    if (![unchangedRecords containsObject:recId]){
    //The unchanged record doesn't exist locally

    if (![updatedRecords containsObject:recId]){
    //The updated record doesn't exist locally

    if (![newRecords containsObject:recId]){
    //The new record doesn't exist locally
    //That means the ongoing record has been deleted from the addressbook,
    //we also have to delete it locally

    [ContactDAO deleteContactWithID:recId inManagedObjectContext:context];

    }

    }
    }

    }

    for (NSNumber *recId in updatedRecords){
    ABRecordID recordID = (ABRecordID)recId.intValue;
    ABRecordRef person = ABAddressBookGetPersonWithRecordID(addressbook, recordID);

    NSDictionary *personDict = [self getPersonDictionaryFromABRecordRef:person];
    if (personDict){
    [ContactDAO updateContactWithFirstName:personDict[@"firstName"] lastName:personDict[@"lastName"] compositeName:personDict[@"compositeName"] picture:personDict[@"picture"] phoneNumbers:personDict[@"phoneNumbers"] recordID:recId inManagedObjectContext:context];
    }
    }

    for (NSNumber *recId in newRecords){
    ABRecordID recordID = (ABRecordID)recId.intValue;
    ABRecordRef person = ABAddressBookGetPersonWithRecordID(addressbook, recordID);

    NSDictionary *personDict = [self getPersonDictionaryFromABRecordRef:person];
    if (personDict){
    [ContactDAO createContactWithFirstName:personDict[@"firstName"] lastName:personDict[@"lastName"] compositeName:personDict[@"compositeName"] picture:personDict[@"picture"] phoneNumbers:personDict[@"phoneNumbers"] recordID:recId inManagedObjectContext:context];
    }

    }

    NSError *dbError;
    [context save:&dbError];

    NSTimeInterval lastSyncTime = [[NSDate date]timeIntervalSince1970];

    [[NSUserDefaults standardUserDefaults]setObject:@(lastSyncTime) forKey:@"LastSyncTime"];
    completion(dbError);
    }


    - (NSDictionary*)getPersonDictionaryFromABRecordRef:(ABRecordRef)person{

    //Get name
    NSString * firstName, *lastName;
    firstName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty));
    lastName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonLastNameProperty));

    firstName = (firstName == nil) ? @"" : firstName;
    lastName = (lastName == nil) ? @"" : lastName;
    NSString *compositeName;

    if ([firstName isEqualToString:@""] && [lastName isEqualToString:@""]){
    return nil;
    }

    if ([lastName isEqualToString:@""]){
    compositeName = [NSString stringWithFormat:@"%@", firstName];
    }
    if ([firstName isEqualToString:@""]){
    compositeName = [NSString stringWithFormat:@"%@", lastName];
    }
    if (![lastName isEqualToString:@""] && ![firstName isEqualToString:@""]){
    compositeName = [NSString stringWithFormat:@"%@ %@", firstName, lastName];
    }

    //Get picture
    CFDataRef imageData = ABPersonCopyImageData(person);
    NSData *data = CFBridgingRelease(imageData);

    //Get phone numbers
    NSMutableSet *phoneNumbers = [[NSMutableSet alloc]init];

    ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);
    for(CFIndex i = 0; i < ABMultiValueGetCount(phones); i++) {

    CFStringRef str = ABMultiValueCopyValueAtIndex(phones, i);
    NSString *num = CFBridgingRelease(str);
    [phoneNumbers addObject:num];
    /*if(str)
    CFRelease(str);*/
    }

    //Save it in dictionary
    NSDictionary *personDict = [[NSDictionary alloc]initWithObjectsAndKeys:firstName, @"firstName",lastName , @"lastName",phoneNumbers,@"phoneNumbers", compositeName, @"compositeName", data, @"picture", nil];

    //Release everything.
    if(phones)
    CFRelease(phones);

    return personDict;

    }

    当涉及索引时, this tutorial应该很好。

    关于ios - 需要创建一个像ABPeoplePickerNavigationController这样的自定义 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29697669/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com