Customizing automatic MFMailComposeViewController opened from UITextView
Asked Answered
C

3

6

I have a simple UITextView with an email link in it. The textview is selectable and detects links. This way, you can click on the email and it opens modally an MFMailComposeViewController view controller.

But, I do some customization at the launch of the app :

[[UINavigationBar appearance] setBarTintColor: myGreyColor];
[[UINavigationBar appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor whiteColor], NSFontAttributeName: myFont}];
[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];

This way, all navigation bars are grey, with white text and white buttons, and the title has a custom font.

My problem is that all these are not applied to the mail composer : the bar is grey and the title is white, but the font is the default helvetica neue and the buttons are the default blue. And, the status bar is black, even though my Info.plist says UIStatusBarStyleLightContent and View controller-based status bar appearance is set to NO.

I know how to customize MFMailComposeViewController when I call it manually, but here it pops up automatically. How can I have my styles applied to it ?

Colleencollege answered 3/3, 2014 at 10:55 Comment(3)
@rdurandI am getting the same problem with MFMailComposeViewController navigation color. can you please suggest me for the same..?Erectile
@APG : I wrote an answer. The best way is to manually build your MFMailComposeViewController and customize it directly. Then intercept the link click in the UITextView and present the mail viewcontroller yourself.Colleencollege
@APG : I updated my answer. After some research, looks like customizing the mail composer is a really bad idea and will get your app to be rejected by Apple. You should use appearanceWhenContainedIn to target your own view controllers when you change the appearance, and leave the mail composer work alone.Colleencollege
C
5

EDIT

Customizing the MFMailComposeViewController's appearance is a really bad idea and will most likely get your app rejected by Apple. The following solution should only be used if you don't intend to submit your app to Apple.


Looks like I solved it, thanks to Ray Wenderlich (again..). Here is the full code :

- (void)viewDidLoad
{
    [super viewDidLoad];

    […] // Initializations

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

    _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];
}
Colleencollege answered 3/3, 2014 at 11:22 Comment(1)
When an email is typed into an NSString and set as the text of the UITextview (i.e. not using an attributed string) then the [URL scheme] should be "mailto"Boatbill
P
0

Then You should go through the following appearance method instead of modifying entire application navigation bar :-

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

Because your MFMailComposeViewController opens into the your application and your are modifying the entire application's navigation bar,So that the reason MFMailComposeViewController's navigationbar is modifying. Using the above appearance method you can modify the selected classes or parent classes through which the derived classes you can be modify,This won't modify MFMailComposeViewController,Because it won't be part of your parent classes.

Pyrex answered 3/3, 2014 at 11:51 Comment(0)
O
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
    }
}
Obfuscate answered 9/12, 2016 at 13:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.