简体   繁体   English

在iOS 7上使用UIBarButtonItem外观的EXC_BAD_ACCESSWhenContainedIn

[英]EXC_BAD_ACCESS with UIBarButtonItem appearanceWhenContainedIn on iOS 7

//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
}

This is giving a EXC_BAD_ACCESS when called in viewDidLoad only on iOS 7 Gold Master and newer. 仅在iOS 7 Gold Master及更新版本的viewDidLoad调用时,才会显示EXC_BAD_ACCESS。 iOS 7 beta 6 and older is fine. iOS 7 beta 6及更早版本很好。

Is there a different way to do this in iOS 7? 在iOS 7中有不同的方法吗?

NSLog("%@", searchBarButton) results in this on iOS7: NSLog("%@", searchBarButton)NSLog("%@", searchBarButton)产生这个:

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

and this on iOS 6 这在iOS 6上

<_UIBarItemAppearance: 0x1c671aa0>

setTitle will fail in iOS7. 在iOS7中, setTitle将失败。

Try below code from this blog: 尝试以下代码来自博客:

-(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];
    }
}

I'm using this without any problems in 7.1, however, it does seem to crash on 7.0.x (device and sim) - hopefully this means they've brought the property back in 7.1, but it also means that we have to use one of the above subview traversing hacks for the interim versions. 我在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"];

UIBarButtonItem 's title property is not available through the UIAppearance proxy. UIBarButtonItemtitle属性不能通过UIAppearance代理获得。

I don't know why it was working in iOS 6, but it's definitely not supposed to. 我不知道为什么它在iOS 6中工作,但它绝对不应该。

The only alternative you seem to have is to "hack" the UISearchBar by crawling its subviews looking for the button and setting the title, but: 您似乎唯一的选择是通过抓取其子视图来寻找按钮并设置标题来“破解” UISearchBar ,但是:

  • it's very fragile, as any implementation change to the subviews structure will break your code 非常脆弱,因为对子视图结构的任何实现更改都会破坏您的代码
  • it's not global you will have to do this on any UISearchBar instance 它不是全局的,你必须在任何UISearchBar实例上执行此操作

According to this answer you can perform this "hack" in the searchDisplayControllerWillBeginSearch: method of UISearchDisplayDelegate like follows: 根据这个答案,您可以在UISearchDisplayDelegatesearchDisplayControllerWillBeginSearch:方法中执行此“hack”,如下所示:

- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
     [theSearchBar setShowsCancelButton:YES animated:NO];

    UIButton *cancelButton;
    UIView *topView = theSearchBar.subviews[0];
    for (UIView *subView in topView.subviews) {
        if ([subView isKindOfClass:NSClassFromString(@"UINavigationButton")]) {
            cancelButton = (UIButton*)subView;
        }
    }
    if (cancelButton) {
        [cancelButton setTitle:@"YourTitle" forState:UIControlStateNormal];
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM