Appearance API - UIBarButtonItem - MPMoviePlayerViewController和Youtube Webview

时间:2012-09-05 21:40:34

标签: iphone objective-c ios5 uinavigationbar uiappearance

我使用Appearance API设置UIBarButtonItem样式,如下所示

[[UIBarButtonItem appearance] setBackgroundImage:barButtonBgImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

这适用于整个应用程序。问题是,如果您点击uiwebview中的YouTube视频,这也会更改加载的YouTube视频的视频观看按钮。

YouTube Examples

添加如下代码:

[[UIBarButtonItem appearanceWhenContainedIn:[MPMoviePlayerViewController class], nil] setBackgroundImage:barButtonBgImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

不会改变任何内容(因为看起来YouTube的内容不仅仅是MPMoviePlayerViewController

如果我理解正确,我也不允许更改YouTube视图的按钮(我也不想这样做)。

有关如何停止在此YouTube视频观看中设置自定义栏按钮图像的任何想法?

如果您想仔细查看,请参阅示例项目:https://dl.dropbox.com/u/80699/BarItemsSample.zip

2 个答案:

答案 0 :(得分:7)

因为你误解了什么剂量的外观当包含在:做。

SDK文档说:

  

要在容器类的实例或层次结构中的实例中包含类的实例的外观,请使用appearanceWhenContainedIn:来获取类的外观代理。

下面的代码就是您在问题中要求的代码。请在问我之前试一试。

对于iOS 5.x,您应该创建UINavigationBar的子类(不需要任何覆盖),例如

//In MJAppDelegate.h:
@interface MyNavigationBar : UINavigationBar
@end

//In MJAppDelegate.m:
@implementation MyNavigationBar
@end

然后你应该编辑你的故事板,让它使用MyNavigationBar作为它的UINavigationController的导航栏。

最后,您可以使用以下代码获得您想要的内容:

[[UIBarButtonItem  appearanceWhenContainedIn:[MyNavigationBar class], nil] setBackgroundImage:barButtonBgImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

对于iOS 6,您只需使用以下代码:

[[UIBarButtonItem  appearanceWhenContainedIn:[UINavigationBar class], [UINavigationController class], nil] setBackgroundImage:barButtonBgImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

答案 1 :(得分:2)

我相信我已经提出了目前可用于此问题的最有效解决方案。不幸的是,Youtube视频播放器是一个名为MPInlineVideoViewController的私人类。不可能在这个类上使用外观代理,无论如何这都是一个黑客攻击。

这是我想出的。我编写它的方式可以在多个地方使用,也可以用来解决其他外观代理问题,例如在UIWebView中填写表单时的后面和下一个UIBarButtonItems。

  

AppDelegate.h

extern NSString * const ToggleAppearanceStyles;
  

AppDelegate.m

NSString * const ToggleAppearanceStyles = @"ToggleAppearanceStyles";

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    NSNotification *note = [NSNotification notificationWithName:ToggleAppearanceStyles object:NULL userInfo:@{@"flag" : @(YES)}];
    [self toggleAppearanceStyles:note];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(toggleAppearanceStyles:) name:ToggleAppearanceStyles object:NULL];

    return YES;
}
-(void)toggleAppearanceStyles:(NSNotification *)note {

    UIImage *barButtonBgImage = nil;
    UIImage *barButtonBgImageActive = nil;

 if([note.userInfo[@"flag"] boolValue]) {

        barButtonBgImage = [[UIImage imageNamed:@"g_barbutton.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 4, 15, 4)];
        barButtonBgImageActive = [[UIImage imageNamed:@"g_barbutton_active.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 4, 15, 4)];
    }

    [[UIBarButtonItem appearance] setBackgroundImage:barButtonBgImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
    [[UIBarButtonItem appearance] setBackgroundImage:barButtonBgImageActive forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];

}
  

MJWebViewController.m

-(void)viewDidAppear:(BOOL)animated {

    [[NSNotificationCenter defaultCenter] postNotificationName:ToggleAppearanceStyles object:NULL userInfo:@{@"flag" : @(NO)}];

    [super viewDidAppear:animated];
}
-(void)viewWillDisappear:(BOOL)animated {
    [[NSNotificationCenter defaultCenter] postNotificationName:ToggleAppearanceStyles object:NULL userInfo:@{@"flag" : @(YES)}];

    [super viewWillDisappear:animated];
}

在上面的代码中,我们将外观样式切换回默认值,因此在加载YouTube播放器时,它会使用默认样式。当前的ViewController已经加载,因此它将具有样式外观。

当YouTube播放器解散时,不会重新加载当前的ViewController,从而保持样式。当前ViewController消失时,样式外观将重新打开。