Appearance API - UIBarButtonItem - MPMoviePlayerViewController and Youtube Webview

I developed a UIBarButtonItem using the Appearance API, like the following

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

This works great throughout the application. The problem is that it also changes the buttons in the YouTube video clips that load if you click the YouTube video on uiwebview .

YouTube Examples

add this code:

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

nothing changes (because it seems that the YouTube thing is not just MPMoviePlayerViewController .

If I understand correctly, I’m also not allowed to change the buttons in the YouTube view (nor do I want this).

Any ideas on how I can stop installing custom button images on this YouTube video?

Here is an example project if you want to take a closer look: https://dl.dropbox.com/u/80699/BarItemsSample.zip

+7
source share
2 answers

I believe that I came up with the most effective solution currently available for this problem. Unfortunately, the Youtube video player has a private class called MPInlineVideoViewController . It is not possible to use an appearance proxy in this class, which in any case will be a hack.

Here is what I came up with. I encoded it so that it could be used in more than one place, and also could be used to solve other problems of the Appearance proxy, such as the reverse and the next UIBarButtonItems when filling out the form in UIWebView.

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

In the above code, we switch the appearance styles to the default values, so when the YouTube player loads, it uses the default styles. The current ViewController is already loaded, so it will have a style.

When the YouTube player deviates, the current ViewController will not restart, thereby preserving the style. When the current ViewController disappears, the styles that appear are turned back on.

+2
source

Because you do not understand what type of dose WhenContainedIn: do.

The SDK document says:

To customize the appearance of class instances contained in an instance of a container class, or instances in a hierarchy , you use the appearance WhenContainedIn: to get the proxy class of the appearance for the class.

The code below doses what you require in your question. Please try before asking me.

For iOS 5.x, you should subclass UINavigationBar (no overrides required), e.g.

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

Then you have to edit your storyboard, let it use MyNavigationBar as your UINavigationController navigation bar.

Finally, you can use the code below to get what you want:

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

For iOS 6, you can simply use the following code:

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

All Articles