1

I'm using the MFMessageComposeViewController and the MFMailComposeViewController. For some reason only the Mail VC is being styled with the colors I want. Here is how I am styling the Navigation bar in the AppDelegate inside the didFinish func.

let navigationBarAppearace = UINavigationBar.appearance()
    navigationBarAppearace.tintColor = Styles.whiteColor()
    navigationBarAppearace.barTintColor = Styles.inputColor()
    navigationBarAppearace.titleTextAttributes = [NSForegroundColorAttributeName:Styles.whiteColor()]
    navigationBarAppearace.isTranslucent = false

But the Message VC is not being styled by the AppDelegate but I'm not sure why not. I tried this but nothing changed. let controller = MFMessageComposeViewController()

        controller.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: Styles.positiveColor()]
        controller.navigationBar.barTintColor = Styles.negativeColor()
        controller.messageComposeDelegate = self

Is the Message VC styled differently? It still shows up with the default white nav bar and the default blue cancel button.

Here is a photo of the Email VC and the Message VC navigations bars. enter image description here enter image description here

As you can see the Message VC is not being styled like the Email VC Navigation bar, but I'm not sure why.

icekomo
  • 9,328
  • 7
  • 31
  • 59
  • Possible duplicate of [How to change color of navigation bar in mfmessagecomposeviewcontroller while presenting it in ios 9](http://stackoverflow.com/questions/33478646/how-to-change-color-of-navigation-bar-in-mfmessagecomposeviewcontroller-while-pr) – JAB Feb 10 '17 at 19:05
  • There doesn't seem to be an answer about my issue on that page. They seem to figure out how to change the Mail controller, but not the Message controller. – icekomo Feb 10 '17 at 19:12

2 Answers2

1

You can create a subclass of UINavigationBar (MyNavigationBar) where you set all needed properties.

Then, as MFMessageComposeViewController inherits from UINavigationController, you can use its initialization method

init(navigationBarClass: AnyClass?, toolbarClass: AnyClass?)

and provide MyNavigationBar class as a parameter.

Eugene Dudnyk
  • 5,553
  • 1
  • 23
  • 48
  • Why does the Mail VC get styled by the AppDelegate but not the Mail VC? – icekomo Feb 10 '17 at 21:05
  • Please clarify your question. I didn't get it. – Eugene Dudnyk Feb 10 '17 at 21:06
  • Why does the navigation bar for MFMailComposeViewController accept the styling set in the AppDelegate file, but the MFMessageComposeViewController does not accept the same styling. – icekomo Feb 10 '17 at 21:15
  • It can use come custom navigation bar which overrides the original one, or it can override inside of its implementation nav bar's properties. It looks like an iOS system issue. You can submit a bug report regarding that. For example, same behavior is with original action sheet. It is using system subclasses of UIButton as its buttons, but they not get appearance properties of UIButton. – Eugene Dudnyk Feb 10 '17 at 21:25
0

The following is for Swift 3/4.

I tried many ways shown on StackOverflow and other sites, including the subclass way mentioned in the above answer. But could not get success in changing color or changing font color of UIBarButtons.

Then tried different way of presenting the MFMessageComposeViewController.

// Configures and returns a MFMessageComposeViewController instance. This is same with no change.
func configuredMessageComposeViewController() -> MFMessageComposeViewController {
    let messageComposeVC = MFMessageComposeViewController()

    let fileManager:FileManager = FileManager.default
    messageComposeVC.messageComposeDelegate = self  //  Make sure to set this property to self, so that the controller can be dismissed!
    messageComposeVC.recipients = [myContactPhone]

    if fileManager.fileExists(atPath: mySendImagePath) {
        if let image = UIImage(contentsOfFile: mySendImagePath) {
            if UIImagePNGRepresentation(image) != nil
            {
                let imageData1: Data = UIImagePNGRepresentation(image)!
                let success = messageComposeVC.addAttachmentData(imageData1, typeIdentifier: "public.data", filename: "image.JPG")

                if(success)
                {
                }
                else{
                }
            }
        }
    }
    return messageComposeVC
}

// Following code is usage of above.
    if (MFMessageComposeViewController.canSendText()) {
        myMessageComposeVC = configuredMessageComposeViewController()

        // old code - Instead of using following way
        //present(messageComposeVC, animated: true, completion: nil)

        // Used this way to use existing navigation bar.
        if let messageComposeVC = myMessageComposeVC {
            messageComposeVC.willMove(toParentViewController: self)
            messageComposeVC.view.frame = self.view.frame
            self.view.addSubview(messageComposeVC.view)
            self.addChildViewController(messageComposeVC)
            messageComposeVC.didMove(toParentViewController: self)
        }
    } else {
        showSendMMSErrorAlert()
        return
    }

// Following code to remove it when returned through delegate.
func messageComposeViewController(_ controller: MFMessageComposeViewController, didFinishWith result: MessageComposeResult) {

    // old code
    //controller.dismiss(animated: true, completion: nil)

    controller.willMove(toParentViewController: nil)
    controller.view.removeFromSuperview()
    controller.removeFromParentViewController()

    if(result.rawValue == 0)
    {
        ... error ...
    } else {
        ... success ...
    }
}

Hope, this is useful for persons like me.

Regards.

SHS
  • 1,414
  • 4
  • 26
  • 43