以下代码在iOS7中正常工作,但在iOS8中没有正常工作(变量recordID
设置正确):
CFErrorRef error = nil;
const ABAddressBookRef addressBook = (ABAddressBookCreateWithOptions (NULL, &error));
ABRecordRef contactRef = ABAddressBookGetPersonWithRecordID (addressBook, recordID);
ABPersonViewController *personViewController = [[ABPersonViewController alloc] init];
personViewController.addressBook = addressBook;
personViewController.displayedPerson = contactRef;
CFRelease(addressBook);
NSArray *displayedProperties = @[@(kABPersonFirstNameProperty),
@(kABPersonLastNameProperty),
@(kABPersonMiddleNameProperty),
@(kABPersonPrefixProperty),
@(kABPersonSuffixProperty),
@(kABPersonOrganizationProperty),
@(kABPersonJobTitleProperty),
@(kABPersonDepartmentProperty),
@(kABPersonEmailProperty),
@(kABPersonBirthdayProperty),
@(kABPersonKindProperty),
@(kABPersonAddressProperty),
@(kABPersonPhoneProperty),
@(kABPersonInstantMessageProperty),
@(kABPersonURLProperty),
@(kABPersonSocialProfileProperty),
@(kABPersonNoteProperty)];
personViewController.displayedProperties = displayedProperties;
personViewController.navigationItem.title = NSLocalizedString(@"CONTACT_DETAILS", nil);
personViewController.allowsActions = YES;
personViewController.allowsEditing = YES; // if NO, no back button is shown
personViewController.personViewDelegate = self;
personViewController.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"ADDRESSES",nil) style:UIBarButtonItemStylePlain target:self action:@selector(personviewDoneButtonPressed:)];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:personViewController];
[self presentViewController:navigationController animated:YES completion:nil];
iOS8中的错误:
allowsEditing
设置为YES
时,会显示联系人,但是
仅显示名称。导航栏左侧显示后退按钮(名为"地址")和右侧的编辑按钮。当。。。的时候
按下编辑按钮,联系人将显示所有字段
除名称外为空,编辑按钮显示为已完成
按钮。如果按下此完成按钮之前没有任何编辑,
显示有关联系人的所有信息。allowsEditing
设置为NO
时,不会显示后退按钮,所以
屏幕再也不能离开了。有人有解决方法吗?
更新:
我现在意识到,模拟器上只出现有时的问题1,尽管总是 在我的设备上。
答案 0 :(得分:5)
montuno(再次感谢),评论我的第一个答案,得到了Apple技术支持如何解决第一个问题的提示,我现在也理解了第二个问题:
1)只显示部分联系人:
Apple声称以下代码错误:ABRecordRef contactRef = ABAddressBookGetPersonWithRecordID (addressBook, recordID);
ABPersonViewController *personViewController = [[ABPersonViewController alloc] init];
personViewController.addressBook = addressBook;
personViewController.displayedPerson = contactRef;
CFRelease(addressBook);
在将addressBook
分配给ABPersonViewController
之后,CFRelease
被错误地释放。
在我的原始代码中,我没有personViewController
语句。但随后静态分析仪警告“存储在addressBook 中的对象的潜在泄漏”。在我插入release语句之后,构建成功而没有警告,因此我假设addressBook
保留了ABPersonViewController
,显然不是这种情况,至少不是iOS8。我现在再次删除了发布声明,得到了警告,但一切正常。
2)缺少后退按钮:
ABPersonViewController
说“重要人物视图控制器的文档必须与导航控制器一起使用才能正常运行。”
所以我做的是以下几点:
我设置了一个navigationItem.backBarButtonItem
,分配给了UINavigationController
一个“完成”按钮,并使用personViewController
初始化了一个新的initWithRootViewController:
,{ {1}}。然后我以模态方式呈现了新的navigationController
显示带有后退按钮的personViewController
,当按下时,呈现视图控制器取消模态显示的导航控制器。
这适用于iOS< 8,但在iOS8中,当allowsEditing
设置为NO
时,未显示后退按钮。
但这显然不是Apple想要展示personViewController
的方式
我认为Apple假设navigationController
已经存在,并呈现当前视图,因此新的personViewController
只会被推到navigationController
的堆栈上。在这种情况下,personViewController
不是rootViewController
的{{1}},而navigationController
会自动显示后退按钮(navigationController
未执行此操作)。如果以这种方式实现,一切都适用于iOS8。
答案 1 :(得分:0)
更新:此黑客不再有效且无用(请参阅我的新回答)
如果有人遇到同样的问题1),这是一个非常脏的解决方法,直到Apple修复错误(我的错误报告仍然打开):
由于在某些情况下需要在显示ABPersonViewController
屏幕后切换编辑按钮两次,因此可以通过编程方式执行此操作:
定义UINavigationController
的{{1}}的属性:
ABPersoViewController
导航控制器显示人物视图控制器后,执行选择器进行切换:
@property (nonatomic, strong) UINavigationController * navigationControllerForPersonViewController;
设置延迟,以便人物视图控制器屏幕可以显示动画。方法[self performSelector:@selector(toggleEditButton) withObject:nil afterDelay:0.7];
定义为:
toggleEditButton
#pragmas需要禁止编译器警告潜在的内存泄漏 结果是实际显示了人物视图控制器的所有选定信息。