在iOS 7上使用UIBarButtonItem外观的EXC_BAD_ACCESSWhenContainedIn

时间:2013-10-01 19:40:34

标签: ios ios7 uisearchbar exc-bad-access

//Set all cancel buttons in search bars to "Done"
id searchBarButton = [UIBarButtonItem appearanceWhenContainedIn:[UISearchBar class], nil];
if([[[UIDevice currentDevice] systemVersion] floatValue] < 7) {
    [searchBarButton setTitle:@"Done"];
} else {
    //Can't do anything here or i get EXC_BAD_ACCESS
}

仅在iOS 7 Gold Master及更新版本的viewDidLoad中调用时,才会显示EXC_BAD_ACCESS。 iOS 7 beta 6及更早版本很好。

在iOS 7中有不同的方法吗?

NSLog("%@", searchBarButton)在iOS7上产生了这个:

2013-10-01 16:14:25.972 MP Staging[12293:a0b] <_UIBarItemAppearance:0x1aaf72d0> <Customizable class: UIBarButtonItem> when contained in ( UISearchBar ) with invocations (null)>

和iOS 6上的这个

<_UIBarItemAppearance: 0x1c671aa0>

3 个答案:

答案 0 :(得分:5)

setTitle将在iOS7中失败。

尝试以下代码来自this博客:

-(void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller{
    self.searchDisplayController.searchBar.showsCancelButton = YES;
    UIButton *cancelButton;
    UIView *topView = self.searchDisplayController.searchBar.subviews[0];
    for (UIView *subView in topView.subviews) {
        if ([subView isKindOfClass:NSClassFromString(@"UINavigationButton")]) {
            cancelButton = (UIButton*)subView;
        }
    }
    if (cancelButton) {
      //Set the new title of the cancel button
        [cancelButton setTitle:@"Annuller" forState:UIControlStateNormal];
    }
}

答案 1 :(得分:2)

我在7.1中使用它没有任何问题,但是,它似乎在7.0.x(设备和SIM卡)上崩溃 - 希望这意味着它们已经将该属性带回7.1,但它也意味着我们必须使用上述子视图中的一个遍历黑客进行临时版本。

    id barButtonAppearanceInSearchBar = [UIBarButtonItem appearanceWhenContainedIn:[UISearchBar class], nil];
    [barButtonAppearanceInSearchBar setTitleTextAttributes:@{NSFontAttributeName:[UIFont fontWithName:@"HelveticaNeue" size:15],
                                                             NSForegroundColorAttributeName : [UIColor blackColor]
                                                             } forState:UIControlStateNormal];
    [barButtonAppearanceInSearchBar setTitle:@"Done"];

答案 2 :(得分:1)

UIBarButtonItem的{​​{1}}属性无法通过title代理提供。

我不知道为什么它在iOS 6中运行,但它绝对不应该。

您似乎唯一的选择是通过抓取其子视图寻找按钮并设置标题来“破解”UIAppearance,但是:

  • 非常脆弱,因为对子视图结构的任何实施更改都会破坏您的代码
  • 它不是全局的,您必须在任何UISearchBar实例
  • 上执行此操作

根据this answer,您可以使用UISearchBar searchDisplayControllerWillBeginSearch:方法执行此“hack”,如下所示:

UISearchDisplayDelegate