Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS 8 UIActivityViewController and UIAlertController button text color uses window's tintColor

In iOS 8, it seems that buttons on UIAlertController (specifically the action sheet type) as well as buttons on the UIActivityViewController get their color from the main window's tintColor.

How can I change the color of the button text? I've tried using the appearance proxy like this:

[[UIButton appearanceWhenContainedIn:[UIActivityViewController class], nil] setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];

But it has no effect. My window's tintColor is white, so the text on the UIActivityViewController buttons is also white, and it cannot be seen. Changing my window's tintColor resolves this issue, but it messes up the rest of the app.

See the screenshot of my UIActivityViewController with a white cancel button with white text on the bottom:

UIActivityViewController with white Cancel button text

The same thing applies to UIActionSheet (yes, I know it's deprecated) and UIAlertController with the actionSheet type.

How can I make the text on these windows readable without changing the tintColor of the entire app?? Thanks in advance!

like image 928
DiscDev Avatar asked Sep 11 '14 18:09

DiscDev


4 Answers

In addition to the global tint color defined for your application, each view controller allows you to override the tint color for just that controller. In this case your best bet would be to set the tintColor on your UIActivityViewController after initializing but before presenting.

UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:items applicationActivities:activities];

//Set the tint color on just the activity controller as needed here before presenting
[activityController.view setTintColor:[UIColor blueColor]];

[self presentViewController:activityController animated:YES completion:nil];

If you are doing this a lot in your app you could use a subclass or a category to avoid code duplication.

like image 66
jlichti Avatar answered Oct 17 '22 02:10

jlichti


This worked for me with the UIAlertController.

[[UIView appearanceWhenContainedIn:[UIAlertController class], nil] setTintColor:[UIColor blackColor]];
like image 45
AndreasZ Avatar answered Oct 17 '22 01:10

AndreasZ


iOS 11

        let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
        activityVC.popoverPresentationController?.sourceView = self.view

        //Set your activity view controller's appearance
        UIButton.appearance().tintColor = .blue

        //Set back to default UIButton appearance
        self.present(activityVC, animated: true, completion: {
            DispatchQueue.main.async {
                UIButton.appearance().tintColor = nil
            }
        })
like image 4
belebeich Avatar answered Oct 17 '22 03:10

belebeich


In iOS 9 I was able to fix this by tinting the view that presented the UIActivityViewController. Unfortunately, in iOS 10/Xcode 8 this stopped working for me. I was trying to tint a Sharing panel so that the cancel button would not have white, invisible looking text.

The only thing that I found to work in iOS 10 is UIButton.appearance().tintColor = UIColor.red. You can set this globally in app delegate (but this tints your nav bar buttons etc too, so you then have to go and tint them another color manually). You can also set this locally in a view, but because it is actually a global theme that gets applied to all Button types, you have to then set it back to another color after if you don't want the next views to pick it up.

Thus I was able to get it working as a tint to just my ActivityController buttons in a 'hackish' way by adding the line above with my tint color after I initialized the UIActivityViewController but before I presented it. And then I set the tint back to my preferred color (white) in the completion handler of the ActivityController presentation function.

ex: // image to share let image = UIImage(named: "Image")

    // set up activity view controller
    let imageToShare = [ image! ]
    let activityViewController = UIActivityViewController(activityItems: imageToShare, applicationActivities: nil)
    activityViewController.popoverPresentationController?.sourceView = self.view 
    UIButton.appearance().tintColor = UIColor.red

    // present the view controller
    self.present(activityViewController, animated: true, completion: {
        DispatchQueue.main.async {
            UIButton.appearance().tintColor = UIColor.white
        }
    })
like image 2
Natalia Avatar answered Oct 17 '22 01:10

Natalia