iOS – UIAppearance appearanceWhenContainedIn issue

2019-04-26 22:20发布

问题:

I'm setting an image for my navigationbar like so:

[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"navbar.png"] forBarMetrics:UIBarMetricsDefault];

Then I don't want this image for classes of MFMessageComposeViewController so I exclude it by doing this:

[[UINavigationBar appearanceWhenContainedIn:[MFMessageComposeViewController class], nil] setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];

But it has no effect (the navbar is still styled with my image inside the MFMessageComposeViewController). What am I missing here?

回答1:

Found out the solution to my problem:

Subclass the MFMessageComposeViewController

In the init method set the backgroundImage of the navigationBar to nil

Voilá!

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self) {
        // Custom initialization
        [self.navigationBar setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];

    }
    return self;
}


回答2:

Just before presenting the MFMessageComposeViewController try

[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"MyUINavigationBarImageClear"] forBarMetrics:UIBarMetricsDefault];

and in the messageComposeViewController:didFinishWithResult: callback reset to

[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"MyUINavigationBarImageFull"] forBarMetrics:UIBarMetricsDefault];

I'm also setting the .navigationBar.tintColor property of the MFMessageComposeViewController to get the cancel button to match my MyUINavigationBarImageClear image.



回答3:

Two ideas here (but not tested):

1) I suspect that trying to override with nil is not going to work - that statement is ignored. What I suggest you do is create a transparent image, and use that as the background for MFMessageComposeViewController.

2) If that fails, then I suspect will have to get very specific on when to use your image, so you will have to replace the first statement with a long list of "when contained in" statements covering your whole class. if you have a subclass that all your view controllers use - some base class - then I believe you can use that instead. Hopefully #1 works!