问题
i have a feedback button in my ios 7 application with MFMailComposeViewController. After the user click this button the mailcomposer open but the statusbar changed to black. Have anybody a idea what can i do?
i have this problem only with ios7. i customizing my app for ios7.
MFMailComposeViewController *mailController = [[MFMailComposeViewController alloc] init];
mailController.mailComposeDelegate = self;
[mailController setSubject:@"Feedback"];
// Fill out the email body tex
NSString *emailBody = [NSString stringWithFormat:@"testest"],
[UIDevice currentDevice].model,
[UIDevice currentDevice].systemVersion];
[mailController setMessageBody:emailBody isHTML:NO];
[mailController setToRecipients:[NSArray arrayWithObjects:@"support@test.com",nil]];
dispatch_async(dispatch_get_main_queue(), ^{
[self presentModalViewController:mailController animated:YES];
}
回答1:
Set the UIApplication statusBarStyle in the completion block of presentViewController for your MFMailComposeViewController. i.e.
MFMailComposeViewController *mailVC = [[MFMailComposeViewController alloc] init];
[self.navigationController presentViewController:mailVC animated:YES completion:^{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}];
You may also need to add and/or set "View controller-based status bar appearance" to NO in your Info.plist file.
回答2:
Try to add category to MFMailComposeViewController
EDIT: this solution works if "View controller-based status bar appearance" == YES
@implementation MFMailComposeViewController (IOS7_StatusBarStyle)
-(UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
-(UIViewController *)childViewControllerForStatusBarStyle
{
return nil;
}
@end
回答3:
Swift solution.
Set View controller-based status bar appearance
to YES
import UIKit
import MessageUI
import AddressBookUI
extension MFMailComposeViewController {
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
override func childViewControllerForStatusBarStyle() -> UIViewController? {
return nil
}
}
extension ABPeoplePickerNavigationController {
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
override func childViewControllerForStatusBarStyle() -> UIViewController? {
return nil
}
}
回答4:
What did the trick for me was:
- Subclass MFMailComposeViewController
Override the two methods as described in answer 6
-(UIStatusBarStyle)preferredStatusBarStyle;
-(UIViewController *)childViewControllerForStatusBarStyle;
Override viewDidLoad as follows:
-(void)viewDidLoad {
[super viewDidLoad];
[self preferredStatusBarStyle];
[self setNeedsStatusBarAppearanceUpdate];
}
回答5:
Solution for Swift3
Add this to your ViewController:
extension MFMailComposeViewController {
open override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
open override var childViewControllerForStatusBarStyle: UIViewController? {
return nil
}
}
Set View controller-based status bar appearance
>> YES as below:
Thanks to @SoftDesigner
Another cleaner solution that may not change other settings in your app. While presenting the Mail VC change the status bar in the completion block:
controller.present(mailComposeViewController, animated: true) {
UIApplication.shared.statusBarStyle = .lightContent
}
回答6:
Some times it will not update the status bar style properly. You should use
[self setNeedsStatusBarAppearanceUpdate];
To say iOS to refresh the status bar style, manually. Hope someone would save some time on knowing it.
[self presentViewController:picker animated:YES completion:^{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
[self setNeedsStatusBarAppearanceUpdate];
}];
回答7:
The easiest swift 3 solution for me was:
extension MFMailComposeViewController {
open override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
UIApplication.shared.statusBarStyle = .lightContent
}
}
回答8:
None of above answers are work for me.
I have two issues.
- Black status bar
- transparent layer on title bar
Solution
Black status - I remove all navigation bar customization
// comment below line in AppDelegate
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"nav_bg"] forBarMetrics:UIBarMetricsDefault];
Transparent title bar - set navigationBarHidden = Yes for MFMailComposeViewController
composeViewController.navigationBarHidden = YES;
回答9:
It seems that initializing the MFMailComposeViewController UIApplication.shared.statusBarStyle will change to .default... so, saving the state before and setting it again after presentation solved the problem for me:
// save the state, otherwise it will be changed
let sbs = UIApplication.shared.statusBarStyle
let mailComposerVC = MailComposerVC()
mailComposerVC.navigationBar.barTintColor = UINavigationBar.appearance().barTintColor
mailComposerVC.navigationBar.tintColor = UINavigationBar.appearance().tintColor
mailComposerVC.navigationBar.barStyle = UINavigationBar.appearance().barStyle
if MFMailComposeViewController.canSendMail() {
APP_ROOT_VC?.present(mailComposerVC, animated: true, completion: {
// reapply the saved state
UIApplication.shared.statusBarStyle = sbs
})
}
public class MailComposerVC: MFMailComposeViewController {
public override var preferredStatusBarStyle: UIStatusBarStyle {
return UIApplication.shared.statusBarStyle
}
public override var childViewControllerForStatusBarStyle : UIViewController? {
return nil
}
}
回答10:
iOS 7 introduces a method prefersStatusBarHidden
, but it won't be so easy to use in this case. You may prefer to use the statusBarHidden
property of UIApplication
while the modal is presented.
回答11:
[self presentViewController:mailViewController animated:YES completion:^(void) { [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES]; }];
回答12:
In my case, I was using "view controller-based status bar appearance" and presenting a modal view controller with a custom segue transition and then presenting the MFMailComposeViewController from there. In this situation, by default, iOS only respects/uses the presenting or "root" view controller's preferredStatusBarStyle
method.
So once I overrode childViewControllerForStatusBarStyle
in my root view controller and preferredStatusBarStyle
in my modal view controller, everything worked as expected... something like this:
// in RootViewController.m ...
- (UIViewController *)childViewControllerForStatusBarStyle {
return self.modalViewController;
}
// in ModalViewController.m ...
- (UIStatusBarStyle)preferredStatusBarStyle {
if (self.mailController != nil)
return UIStatusBarStyleDefault;
return UIStatusBarStyleLightContent;
}
回答13:
I am building an application in iOS8 and have had issues with the status bar with all native functions such as the mail composer, the camera, etc.. The following will solve your issues:
Put the following in your plist file
<key>UIStatusBarHidden</key>
<false/>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
If you are using the add row feature in storyboard, the UIViewControllerBasedStatusBarAppearance is not an option. Also when adding a row it asks for BOOLEAN (YES/NO). It cannot be a NO string in the source code it must be a false boolean. Open the plist as source code instead and add the above rows. Remove your old attempts. You will now be able to successfully apply the code snippets given in so many incomplete answers found on the net.
You can now add global changes in the app delegate file and/or overrides in the controllers themselves. Without the above being in place all the stack overflow code I have tried has failed when using a native function. Now all is working perfectly.
As a test, replace any calls to any onboard "completion" calls with
completion:^{[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];}
来源:https://stackoverflow.com/questions/18945390/mfmailcomposeviewcontroller-in-ios-7-statusbar-are-black