自定义从UITextView打开的自动MFMailComposeViewController

6
我有一个简单的UITextView,其中包含一个电子邮件链接。文本视图是可选择的,可以检测链接。这样,您就可以单击该电子邮件并模态地打开MFMailComposeViewController视图控制器。
但是,在应用程序启动时,我进行了一些自定义:
[[UINavigationBar appearance] setBarTintColor: myGreyColor];
[[UINavigationBar appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor whiteColor], NSFontAttributeName: myFont}];
[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];

这样,所有的导航栏都是灰色的,文字和按钮是白色的,标题有自定义的字体。

我的问题是这些并没有应用到邮件编辑器上:栏是灰色的,标题是白色的,但字体是默认的Helvetica Neue,按钮是默认的蓝色。而且,状态栏是黑色的,尽管我的Info.plist文件中设置了UIStatusBarStyleLightContentView controller-based status bar appearanceNO

我知道如何在手动调用MFMailComposeViewController时自定义,但这里它是自动弹出的。该如何应用我的样式?


@rdurand,我在MFMailComposeViewController导航颜色方面遇到了相同的问题。你能否为此提供建议? - Anand Gautam
@APG:我写了一个答案。最好的方法是手动构建MFMailComposeViewController并直接自定义它。然后在UITextView中拦截链接点击并自己呈现邮件视图控制器。 - rdurand
@APG:我更新了我的回答。经过一些研究,似乎自定义邮件编辑器是一个非常糟糕的想法,会导致你的应用被苹果拒绝。当你改变外观时,你应该使用appearanceWhenContainedIn来针对你自己的视图控制器,并让邮件编辑器保持原样。 - rdurand
3个回答

5

编辑

定制 MFMailComposeViewController 的外观是一个非常糟糕的想法,很可能会导致您的应用被苹果拒绝。如果您不打算将应用提交给苹果,则应仅使用以下解决方案。


看起来我已经解决了这个问题,感谢 Ray Wenderlich(再次感谢)。以下是完整的代码:

- (void)viewDidLoad
{
    [super viewDidLoad];

    […] // Initializations

    // Link detection
    [_textView.attributedText addAttribute:NSLinkAttributeName value:@"mail://contact" range:[[content string] rangeOfString:@"contact@mymail.com"]];

    _textView.delegate = self;

}

// Handle the link tap yourself
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange {

    if ([[URL scheme] isEqualToString:@"mail"]) {

        MFMailComposeViewController *mailVC = [[MFMailComposeViewController alloc] init];
        [mailVC setToRecipients:@[@"contact@ mymail.com"]];
        [mailVC setSubject:@"About QuickReminder for iOS"];
        mailVC.mailComposeDelegate = self;

        // Re-set the styling
        [mailVC.navigationBar setBarTintColor:myGreyColor];
        [mailVC.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor whiteColor], NSFontAttributeName: myFont}];
        [mailVC.navigationBar setTintColor:[UIColor whiteColor]];

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

        return NO;
    }
    return YES;
}

- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
    // Notifies users about errors associated with the interface
    switch (result)
    {
        case MFMailComposeResultCancelled:
            NSLog(@"Result: canceled");
            break;
        case MFMailComposeResultSaved:
            NSLog(@"Result: saved");
            break;
        case MFMailComposeResultSent:
        {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Result" message:@"Mail Sent Successfully" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
            [alert show];
        }
            break;
        case MFMailComposeResultFailed:
            NSLog(@"Result: failed");
            break;
        default:
            NSLog(@"Result: not sent");
            break;
    }

    [controller dismissViewControllerAnimated:YES completion:nil];
}

当将电子邮件键入NSString并将其设置为UITextview的文本(即不使用属性字符串)时,[URL scheme]应为“mailto”。 - s.ka

0

那么,您应该遵循以下外观方法,而不是修改整个应用程序导航栏:-

[[UINavigationBar appearanceWhenContainedIn:<#(__unsafe_unretained Class<UIAppearanceContainer> *), ...#>, nil]setTintColor:[UIColor greenColor]];

因为您的MFMailComposeViewController打开到您的应用程序中,并且您正在修改整个应用程序的导航栏,所以这就是MFMailComposeViewController的导航栏被修改的原因。 使用上述外观方法,您可以通过选定的类或父类来修改派生类,从而可以进行修改,但这不会修改MFMailComposeViewController,因为它不是您的父类的一部分。


0

Swift 3:

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

    open override func viewDidLoad() {
        super.viewDidLoad()
        navigationBar.isTranslucent = false
        navigationBar.isOpaque = false
        navigationBar.barTintColor = UIColor.white
        navigationBar.tintColor = UIColor.white
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接