我有两种方法可以在视图控制器的UINavigationItem中切换右边的条形按钮项。它主要是在点击搜索按钮时在导航栏中显示搜索栏,并在用户执行搜索时隐藏搜索栏
- (void)displaySearchUI
{
[self.mainNavigationController.topViewController.navigationItem setRightBarButtonItems:[self searchOpenItems] animated:YES];
[self.searchBar becomeFirstResponder];
}
- (void)dismissSearchUI
{
[self.mainNavigationController.topViewController.navigationItem setRightBarButtonItems:[self searchClosedItems] animated:YES];
}
- (NSArray *)searchClosedItems
{
return @[[self someCustomItem],
[self someOtherItem],
[self searchButtonItem],
];
}
- (NSArray *)searchOpenItems
{
return @[[self someCustomItem],
[self someOtherItem],
[self searchBarItem],
];
}
从searchButtonItem返回的项使用带有图像的UIBarButtonItem,而从searchBarItem返回的项具有UISearchBar的自定义视图。每个搜索状态中每个项目中的其他项目相同。
当我调用displaySearchUI时,搜索栏成为第一个响应者会打开一个弹出框以显示一些搜索建议。当用户解除弹出窗口时,通过popoverControllerDidDismissPopover:delegate方法调用dismissSearchUI。但是在那时,应用程序经常遇到UINavigationBar中的崩溃:
-[CALayer enumerateObjectsUsingBlock:]: unrecognized selector sent to instance 0x7de9ac80
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[CALayer enumerateObjectsUsingBlock:]: unrecognized selector sent to instance 0x7de9ac80'
*** First throw call stack:
(
0 CoreFoundation 0x056f0946 __exceptionPreprocess + 182
1 libobjc.A.dylib 0x05379a97 objc_exception_throw + 44
2 CoreFoundation 0x056f85c5 -[NSObject(NSObject) doesNotRecognizeSelector:] + 277
3 CoreFoundation 0x056413e7 ___forwarding___ + 1047
4 CoreFoundation 0x05640fae _CF_forwarding_prep_0 + 14
5 UIKit 0x03ba38aa -[UINavigationBar _setLeftViews:rightViews:] + 3774
6 UIKit 0x03b8f77e -[UINavigationItem updateNavigationBarButtonsAnimated:] + 186
7 UIKit 0x03b901a0 -[UINavigationItem setObject:forLeftRightKeyPath:animated:] + 600
8 UIKit 0x03b9100a -[UINavigationItem setRightBarButtonItems:animated:] + 104
9 MyApp 0x0028088b -[DisplayManager dismissSearchUI] + 283
我不确定这里到底发生了什么。似乎是否设置项目是动画的。它也只有在用户点击弹出窗口之外时才会发生。如果我以编程方式关闭popover并调用dismissSearchUI,则没有崩溃(我想是由于动画发生的顺序不同,或者当用户解除弹出窗口与程序解雇时UI中的某些状态差异。我已经试图解决这个问题:
#pragma mark - UIPopoverControllerDelegate
- (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController
{
[self dismissSearchSuggestionsUI];
return NO;
}
- (void)dismissSearchSuggestionsUI
{
[self.popoverController dismissPopoverAnimated:YES];
[self.displayManager dismissSearchUI];
}
但是我在这里得到了一个EXC_BAD_ACCESS崩溃,(有一个类似的堆栈跟踪让我相信它是同一个问题,只是因为时间问题而出现不同的症状)。
有没有人遇到这样的事情,有没有办法解决这个问题而不必完全禁用手动用户popover解雇?
答案 0 :(得分:0)
呸,我发布后就知道了。通过修改dismissSearchUI的方法来做到这一点:
- (void)dismissSearchUI
{
[self.searchBar resignFirstResponder]
[self.mainNavigationController.topViewController.navigationItem setRightBarButtonItems:[self searchClosedItems] animated:YES];
}
我解决了这个问题。我认为搜索栏会在用户执行搜索时重新签名自己的第一响应者,但当用户手动取消搜索时会自动发生这种情况,导致其中的条形按钮项目被删除来自导航栏。