4

I am working on an iOS app where user can email and send sms.I am using MFMailComposeViewController & MFMessageComposeViewController for sending email and SMS but sometimes Cancel and Send button appear over composer and sometime it doesn't appear at all. This issue is random and I have tried alot to figure out. Any help will be greatly appreciated. Code

  MFMailComposeViewController *mail = [[MFMailComposeViewController alloc] init];
  mail.mailComposeDelegate = self;
  [mail setSubject:Email_Subject];
  [mail setMessageBody:Share_Message isHTML:NO];
  [mail setToRecipients:@[@""]];
  [self presentViewController:mail animated:YES completion:NULL];

I have implemented MFMailComposeViewControllerDelegate in my viewController in header file.

Zalak Patel
  • 1,937
  • 3
  • 26
  • 44
iOSGeek
  • 115
  • 11
  • are you checking in device or simulator? – HardikDG Feb 12 '17 at 16:37
  • I am testing on iPhone 6 – iOSGeek Feb 12 '17 at 18:19
  • Sounds like a presentation or a layout issue. Are you using AutoLayout? Is there a space where the navigation bar is missing or does it look like the bar may be above the top of the screen? – Joe Collins Feb 12 '17 at 18:41
  • cross check whether you have customized navigation bar tint color or background color . try removing them and check once – Vinodh Feb 13 '17 at 03:16
  • 1
    @JoeCollins Yes i am using autolayout. Its random sometimes there is empty bar and sometime mail subject bar appears at top of all. – iOSGeek Feb 13 '17 at 15:14
  • I'm finding this too. I don't know what's causing it yet, but I have found a means to reproduce it-- so at least in my case it's not fully random. In my case it can be reproduced when you enter zoomed or non-zoomed mode on the iPhone device, and then open the app and use the MFMailComposeViewController. This is the zoom under Display & Brightness > DISPLAY ZOOM. – Chris Prince Feb 23 '18 at 20:47
  • Also, in my case, the buttons are still "there"-- in the sense that you can tap on them. You just can't see them. – Chris Prince Feb 23 '18 at 21:08

2 Answers2

3

OK, I've got some traction on this finally. My problem stemmed in part from me changing nav bar colors in my app delegate (Swift):

    UINavigationBar.appearance().barTintColor = UIColor.black
    UIApplication.shared.statusBarStyle = .lightContent

    // To get my hamburger menu white colored
    UINavigationBar.appearance().tintColor = UIColor.white

Due to this, and some interaction with the Zoomed mode (see my comment above), sometimes I'd get the Cancel/Send buttons set to white color in my mail controller. Like this:

enter image description here

I'll show you my class (Objective C) that displays the mail controller, which now works for me to solve the problem in this question. Note that the line:

[UINavigationBar appearance].tintColor = appleBlueTintColor;

is really the secret sauce in all of this:

#import <MessageUI/MessageUI.h>

@interface SendEmail : MFMailComposeViewController

// Returns nil if can't send email on this device. Displays an alert before returning in this case.
- (id) initWithParentViewController: (UIViewController *) parent;

// Show the email composer.
- (void) show;

// Message to append to the bottom of support emails. The string doesn't contain HTML.
+ (NSString *) getVersionDetailsFor: (NSString *) appName;

@end

@interface SendEmail ()<MFMailComposeViewControllerDelegate>
@property (nonatomic, weak) UIViewController *myParent;
@property (nonatomic, strong) UIColor *previousBarTintColor;
@property (nonatomic, strong) UIColor *previousTintColor;
@end

#import "SendEmail.h"
#import <sys/utsname.h>
@implementation SendEmail

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

// Using this init method depends on the `show` method being called immediately after-- to reset the nav bar colors back to what they were originally.
- (id) initWithParentViewController: (UIViewController *) theParent {
    if (![MFMailComposeViewController canSendMail]) {
        NSString *title = @"Sorry, the app isn't allowed to send email.";
        NSString *message = @"Have you configured this device to send email?";
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
        [alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
        [theParent presentViewController:alert animated:YES completion:nil];
        return nil;
    }

    // The default app nav bar color is black-- and that looks bad on the mail VC. Need to change and then set back both the barTintColor and the tintColor (in the `show` method).

    self.previousBarTintColor = [UINavigationBar appearance].barTintColor;
    self.previousTintColor = [UINavigationBar appearance].tintColor;

    [[UINavigationBar appearance] setBarTintColor:[UIColor whiteColor]];

    // I got this color from the digital color meter-- this is what it is supposed to be on the Cancel/Send buttons.
    UIColor *appleBlueTintColor = [UIColor colorWithRed:31.0/255.0 green:134.0/255.0 blue:254.0/255.0 alpha:1.0];
    [UINavigationBar appearance].tintColor = appleBlueTintColor;

    self = [super init];
    if (self) {
        self.mailComposeDelegate = self;
        self.myParent = theParent;
    }

    return self;
}

- (void) show {
    [self.myParent presentViewController:self animated:YES completion:^{
        [[UINavigationBar appearance] setBarTintColor: self.previousBarTintColor];
        [UINavigationBar appearance].tintColor = self.previousTintColor;
    }];
}

- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
    [self.myParent dismissViewControllerAnimated:YES completion:nil];
}

+ (NSString *) getVersionDetailsFor: (NSString *) appName;
{
    NSMutableString *message = [NSMutableString string];
    [message appendString:@"\n\n\n--------------\n"];
    [message appendFormat:@"iOS version: %@\n", [[UIDevice currentDevice] systemVersion]];
    [message appendFormat:@"%@ version: %@ (%@)\n", appName,
     [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"],
     [[NSBundle mainBundle]objectForInfoDictionaryKey:@"CFBundleVersion"]];
    [message appendFormat:@"Hardware: %@\n", [self machineName]];

    return message;
}

// See http://stackoverflow.com/questions/11197509/ios-iphone-get-device-model-and-make
+ (NSString *) machineName;
{
    struct utsname systemInfo;
    uname(&systemInfo);

    return [NSString stringWithCString:systemInfo.machine
                              encoding:NSUTF8StringEncoding];
}

@end
Chris Prince
  • 7,288
  • 2
  • 48
  • 66
1

My problem was the below line. Just comment this line as it makes the Barbutton title colour Clear.

UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.clear], for: .normal)
//comment this line
Nupur Sharma
  • 1,106
  • 13
  • 15