【问题标题】:MFMailComposeViewController in iOS 7 statusbar are blackiOS 7 状态栏中的 MFMailComposeViewController 为黑色
【发布时间】:2013-09-22 15:19:25
【问题描述】:

我的 ios 7 应用程序中有一个带有 MFMailComposeViewController 的反馈按钮。用户单击此按钮后,mailcomposer 打开,但状态栏变为黑色。有人知道我能做什么吗?

我只有 ios7 才有这个问题。我正在为 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];
}

【问题讨论】:

    标签: ios ios7 mfmailcomposeviewcontroller


    【解决方案1】:

    在 presentViewController 的完成块中为您的 MFMailComposeViewController 设置 UIApplication statusBarStyle。即

        MFMailComposeViewController *mailVC = [[MFMailComposeViewController alloc] init];
        [self.navigationController presentViewController:mailVC animated:YES completion:^{
            [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
        }];
    

    您可能还需要在 Info.plist 文件中添加和/或设置“基于控制器的状态栏外观”为 NO。

    【讨论】:

    • 如果您在 Info.plist 中进行更改,我认为您在哪里执行 setStatusBarStyle 并不重要,因为它会成为应用程序的全局设置。
    • 这不应该被标记为正确答案,因为此时preferredStatusBarStyle 是无用的
    • @mackinra:不完全是。我在我的 plist 和应用程序委托上设置了它,但在我的情况下,MailViewComposeViewController 将它从白色覆盖为黑色。这个解决方案已经修复了它,尽管它很奇怪。
    • 我必须使用[self presentViewController:mailVC... 而不是[self.navigationController...
    • [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];现在已弃用,所以我不知道该怎么办
    【解决方案2】:

    尝试将类别添加到 MFMailComposeViewController

    编辑:如果“查看基于控制器的状态栏外观”== YES,则此解决方案有效

    @implementation MFMailComposeViewController (IOS7_StatusBarStyle)
    
    -(UIStatusBarStyle)preferredStatusBarStyle
    {
       return UIStatusBarStyleLightContent;
    }
    
    -(UIViewController *)childViewControllerForStatusBarStyle
    {
       return nil;
    }
    
    @end
    

    【讨论】:

    • 这不起作用,因为视图控制器及其状态栏完全由不同的进程(MailCompositionService)呈现。这只会影响在外部进程加载时动画的预览视图控制器。
    • 如果你重写 MFMailComposeViewController 类并只实现这两个方法就可以了!
    • 这行得通!我添加了完全相同的类别,childViewControllerForStatusBarStyle 做得很好!没有它,虽然什么都不会发生。
    • 这对我也有用。如果你想让设置全局化,凯勒的答案会起作用,但如果你不这样做,这个可以解决问题。
    • 您不应该覆盖类别中的现有方法。这会导致意外行为。你可以在这里阅读更多相关信息:mikeash.com/pyblog/…
    【解决方案3】:

    快速解决方案。 将View controller-based status bar appearance 设置为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
        }
    }
    

    【讨论】:

    • 这似乎是 iOS 9 的正确答案。(好吧,在删除“public”关键字之后。)
    • 如果您想要更广泛的解决方案,您可以改为扩展 UINavigationController 并覆盖 PreferredStatusBarStyle 和 childViewControllerForStatusBarStyle。这适用于 MFMailComposeViewController 和通过短信和打印共享时呈现的共享表。 (我没有测试 ABPeoplePickerNavigationController,因为我没有在我的应用程序中使用它。)
    • 好主意,完美运行。尝试了一堆不同的 swift 方法,包括上面的 completionHanlder,但扩展绝对是要走的路!!!
    • 在 Swift 3 中:扩展 MFMailComposeViewController { override open var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent } override open var childViewControllerForStatusBarStyle: UIViewController? { 返回零 } }
    【解决方案4】:

    对我来说诀窍是:

    • MFMailComposeViewController 子类
    • 覆盖答案 6 中描述的两种方法

      -(UIStatusBarStyle)preferredStatusBarStyle;

      -(UIViewController *)childViewControllerForStatusBarStyle;

    • 如下覆盖viewDidLoad:

      -(void)viewDidLoad {
      [super viewDidLoad];
      [self preferredStatusBarStyle];
      [self setNeedsStatusBarAppearanceUpdate];
      }

    【讨论】:

    • 根据我的经验,覆盖这两种方法就足够了。
    • 行 [self preferredStatusBarStyle]; 是什么意思?做?它只获取样式,然后什么都不做。
    【解决方案5】:

    Swift3解决方案

    将此添加到您的 ViewController:

    extension MFMailComposeViewController {
        open override var preferredStatusBarStyle: UIStatusBarStyle {
            return .lightContent
        }
        open override var childViewControllerForStatusBarStyle: UIViewController? {
            return nil
        }
    }
    

    设置View controller-based status bar appearance >> YES如下:

    感谢@SoftDesigner

    另一个可能不会更改应用中其他设置的更清洁解决方案。显示 Mail VC 时,更改完成块中的状态栏:

    controller.present(mailComposeViewController, animated: true) {
                UIApplication.shared.statusBarStyle = .lightContent
            }
    

    【讨论】:

    • 由于在 iOS 9 中设置 UIApplication.shared.statusBarStyle 已被弃用,因此扩展程序成功了!
    【解决方案6】:

    有时它不会正确更新状态栏样式。你应该使用

     [self setNeedsStatusBarAppearanceUpdate];
    

    要说iOS刷新状态栏样式,手动。希望有人能节省一些时间来了解它。

    [self presentViewController:picker animated:YES completion:^{
        [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
         [self setNeedsStatusBarAppearanceUpdate];
    }];
    

    【讨论】:

      【解决方案7】:

      对我来说最简单的 swift 3 解决方案是:

      extension MFMailComposeViewController {
      
          open override func viewDidAppear(_ animated: Bool) {
              super.viewDidAppear(animated)
      
              UIApplication.shared.statusBarStyle = .lightContent
          }
      }
      

      【讨论】:

        【解决方案8】:

        以上答案都不适合我。

        我有两个问题。

        1. 黑色状态栏
        2. 标题栏透明层

        解决方案

        1. 黑色状态 - 我删除了所有导航栏自定义

          // 在 AppDelegate 中的行下注释

          [[UINavigationBar 外观] setBackgroundImage:[UIImage imageNamed:@"nav_bg"] forBarMetrics:UIBarMetricsDefault];

        2. 透明标题栏 - 为 MFMailComposeViewController 设置 navigationBarHidden = Yes

          composeViewController.navigationBarHidden = YES;

        【讨论】:

          【解决方案9】:

          似乎初始化 MFMailComposeViewController UIApplication.shared.statusBarStyle 将更改为 .default... 所以,保存之前的状态并在演示后再次设置它为我解决了问题:

              // 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 引入了一个方法prefersStatusBarHidden,但在这种情况下它不会那么容易使用。在显示模式时,您可能更喜欢使用UIApplicationstatusBarHidden 属性。

            【讨论】:

            • thx 4 你的答案。我测试它: [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];同样的问题:(
            【解决方案11】:
            [self presentViewController:mailViewController animated:YES completion:^(void) { [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
            
            [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES]; }];
            

            【讨论】:

              【解决方案12】:

              在我的例子中,我使用“基于视图控制器的状态栏外观”并呈现一个带有自定义 segue 转换的模态视图控制器,然后从那里呈现 MFMailComposeViewController。在这种情况下,默认情况下,iOS 仅尊重/使用 presenting 或“root”视图控制器的 preferredStatusBarStyle 方法。

              所以一旦我在我的根视图控制器中覆盖childViewControllerForStatusBarStyle在我的模态视图控制器中preferredStatusBarStyle,一切都按预期工作......像这样:

              // in RootViewController.m ...
              - (UIViewController *)childViewControllerForStatusBarStyle {
                  return self.modalViewController;
              }
              
              // in ModalViewController.m ...
              - (UIStatusBarStyle)preferredStatusBarStyle {
                  if (self.mailController != nil)
                      return UIStatusBarStyleDefault;
                  return UIStatusBarStyleLightContent;
              }
              

              【讨论】:

                【解决方案13】:

                我正在 iOS8 中构建一个应用程序,但在状态栏的所有本机功能(如邮件编写器、相机等)方面遇到了问题。以下将解决您的问题:

                将以下内容放入您的 plist 文件中

                  <key>UIStatusBarHidden</key>
                  <false/>
                  <key>UIViewControllerBasedStatusBarAppearance</key>
                  <false/>
                

                如果您在情节提要中使用添加行功能,则 UIViewControllerBasedStatusBarAppearance 不是一个选项。此外,当添加一行时,它会要求 BOOLEAN (YES/NO)。它不能是源代码中的 NO 字符串,它必须是 false 布尔值。改为将 plist 作为源代码打开并添加上述行。删除您的旧尝试。您现在可以成功应用在网上找到的许多不完整答案中给出的代码 sn-ps。

                您现在可以在应用委托文件中添加全局更改和/或在控制器本身中覆盖。如果没有上述内容,我尝试过的所有堆栈溢出代码在使用本机函数时都失败了。现在一切正常。

                作为测试,将对任何板载“完成”调用的调用替换为

                    completion:^{[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];}
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2014-08-31
                  • 2014-08-05
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多