iOS8错误:ABPersonViewController不显示属性&;后退按钮
以下代码在iOS7中正常工作,但在iOS8中不能正常工作(变量iOS8错误:ABPersonViewController不显示属性&;后退按钮,ios8,abaddressbook,abpersonviewcontroller,Ios8,Abaddressbook,Abpersonviewcontroller,以下代码在iOS7中正常工作,但在iOS8中不能正常工作(变量recordID设置正确): iOS8中的bug: 当allowediting设置为YES时,会显示联系人,但 仅显示名称。导航栏左侧显示后退按钮(名为“地址”),右侧显示编辑按钮。当 按下编辑按钮,联系人显示为所有字段 除名称外为空,编辑按钮显示为“完成” 按钮如果按下此“完成”按钮之前未进行任何编辑, 将显示有关联系人的所有信息 当allowediting设置为NO时,不会显示后退按钮,因此 屏幕不能再留下 有人有解决办法吗 更新
recordID
设置正确):
iOS8中的bug:
allowediting
设置为YES
时,会显示联系人,但
仅显示名称。导航栏左侧显示后退按钮(名为“地址”),右侧显示编辑按钮。当
按下编辑按钮,联系人显示为所有字段
除名称外为空,编辑按钮显示为“完成”
按钮如果按下此“完成”按钮之前未进行任何编辑,
将显示有关联系人的所有信息allowediting
设置为NO
时,不会显示后退按钮,因此
屏幕不能再留下到现在为止,我意识到问题1只有有时会发生在模拟器上,尽管总是发生在我的设备上 更新:此黑客不再有效,完全无用(请参阅我的新答案) 如果有人有上述相同的问题1),在苹果修复该漏洞之前,这里有一个非常肮脏的解决方法(我的漏洞报告仍然开放):
由于在某些情况下需要在显示
ABPersonViewController
屏幕后切换编辑按钮两次,因此可以通过编程方式执行此操作:
为显示ABPersoViewController
的UINavigationController定义一个属性:
@property (nonatomic, strong) UINavigationController * navigationControllerForPersonViewController;
导航控制器显示person view控制器后,执行选择器进行切换:
[self performSelector:@selector(toggleEditButton) withObject:nil afterDelay:0.7];
设置延迟,以便“个人视图控制器”屏幕可以显示动画。方法toggleEditButton
定义为:
- (void)toggleEditButton
{
UIBarButtonItem *editButton = self.navigationControllerForPersonViewController.topViewController.navigationItem.rightBarButtonItem;
id target = editButton.target;
SEL editAction = editButton.action;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[target performSelector:editAction withObject:editButton];
[target performSelector:editAction withObject:editButton];
#pragma clang diagnostic pop
}
需要使用#pragmas来抑制编译器对潜在内存泄漏的警告。
结果是,person view controller的所有选定信息都会显示出来。montuno(再次感谢),他对我的第一个答案进行了评论,从苹果技术支持那里得到了如何解决第一个问题的提示,我现在也明白了第二个问题:
1) 仅显示部分联系人:
苹果声称以下代码是错误的:
ABRecordRef contactRef = ABAddressBookGetPersonWithRecordID (addressBook, recordID);
ABPersonViewController *personViewController = [[ABPersonViewController alloc] init];
personViewController.addressBook = addressBook;
personViewController.displayedPerson = contactRef;
CFRelease(addressBook);
这里的地址簿
在分配给ABPersonViewController
后被错误释放
在我的原始代码中,我没有CFRelease
语句。但随后静态分析仪发出“地址簿中存储的对象可能泄漏”的警告“。插入发布语句后,生成成功,没有任何警告,因此我假设personViewController
保留了地址簿
,情况显然不是这样,至少iOS8没有。我现在再次删除了发布语句,得到了警告,但一切正常
2) 缺少后退按钮:
ABPersonViewController
的文档中说“重要人物视图控制器必须与导航控制器一起使用才能正常工作。”
因此,我所做的如下:
我设置了一个ABPersonViewController
,分配给它的navigationItem.BackbarButtonim
a“完成”“按钮,并使用此personViewController
初始化了一个新的UINavigationController
,使用initWithRootViewController:
。然后我以模式呈现了新的navigationController
。
显示带有后退按钮的personViewController
,按下后,演示视图控制器将取消模式演示的导航控制器。
这在iOS<8上运行良好,但在iOS 8中,当allowsdediting
设置为NO
时,不会显示后退按钮
但这显然不是苹果想要显示的personViewController
:
我认为苹果假定navigationController
已经存在,并呈现当前视图,因此新的personViewController
被推到navigationController
的堆栈上。在这种情况下,personViewController
不是navigationC的rootViewController
控制器
,导航控制器
会自动显示一个后退按钮(对于rootViewController
),如果以这种方式实现,iOS8也可以正常工作。我在iOS8上也遇到了问题#1,仅在设备上(而不是在模拟器中)-虽然在我的情况下,我将allowsEditing设置为NO。您知道在禁用编辑时如何解决此问题吗?不幸的是,我不知道如何解决此问题。也许您也可以提交一份错误报告,以表明我不是唯一一个有此问题的人?仅供参考-Apple提供的演示源代码“QuickContacts”(可从Xcode中获得)演示如何使用ABPersonViewController。奇怪的是,它似乎在iOS 8上也能正常工作,甚至在设备上也是如此。然而,即使经过仔细分析,我也无法解释为什么我在自己的应用程序中会看到不同的行为。我不确定这是否可行,但如果新版本的ABPersonViewController使用未初始化的变量,那么e行为取决于其他代码在执行ABPersonViewController之前留下的内存,即有时可以工作,有时不工作。实际上,这发生在我随错误报告提交给苹果的一个小演示程序上。这个演示程序有时在模拟器中工作,但不总是,并且总是在设备上失败这可以解释我所看到的。解决第一个问题的方法对我也有帮助。但我有一点其他的情况:在第一次访问ABPersonViewController的addressBook属性之后,它会
ABRecordRef contactRef = ABAddressBookGetPersonWithRecordID (addressBook, recordID);
ABPersonViewController *personViewController = [[ABPersonViewController alloc] init];
personViewController.addressBook = addressBook;
personViewController.displayedPerson = contactRef;
CFRelease(addressBook);