I am using new UIAlertController for showing alerts. I have this code:
// nil titles break alert interface on iOS 8.0, so we\'ll be using empty strings
UIAle
There is a problem with setting the tint color on the view after presenting; even if you do it in the completion block of presentViewController:animated:completion:, it causes a flicker effect on the color of the button titles. This is sloppy, unprofessional and completely unacceptable.
Other solutions presented depend on the view hierarchy remaining static, something that Apple is loathe to do. Expect those solutions to fail in future releases of iOS.
The one sure-fire way to solve this problem and to do it everywhere, is via adding a category to UIAlertController and swizzling the viewWillAppear.
The header:
//
// UIAlertController+iOS9TintFix.h
//
// Created by Flor, Daniel J on 11/2/15.
//
#import
@interface UIAlertController (iOS9TintFix)
+ (void)tintFix;
- (void)swizzledViewWillAppear:(BOOL)animated;
@end
The implementation:
//
// UIAlertController+iOS9TintFix.m
//
// Created by Flor, Daniel J on 11/2/15.
//
#import "UIAlertController+iOS9TintFix.h"
#import
@implementation UIAlertController (iOS9TintFix)
+ (void)tintFix {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Method method = class_getInstanceMethod(self, @selector(viewWillAppear:));
Method swizzle = class_getInstanceMethod(self, @selector(swizzledViewWillAppear:));
method_exchangeImplementations(method, swizzle);});
}
- (void)swizzledViewWillAppear:(BOOL)animated {
[self swizzledViewWillAppear:animated];
for (UIView *view in self.view.subviews) {
if (view.tintColor == self.view.tintColor) {
//only do those that match the main view, so we don't strip the red-tint from destructive buttons.
self.view.tintColor = [UIColor colorWithRed:0.0 green:122.0/255.0 blue:1.0 alpha:1.0];
[view setNeedsDisplay];
}
}
}
@end
Add a .pch (precompiled header) to your project and include the category:
#import "UIAlertController+iOS9TintFix.h"
Make sure you register your pch in the project properly, and it will include the category methods in every class that uses the UIAlertController.
Then, in your app delegates didFinishLaunchingWithOptions method, import your category and call
[UIAlertController tintFix];
and it will automatically propagate to every single instance of UIAlertController within your app, whether launched by your code or anyone else's.
This solution works for both iOS 8.X and iOS 9.X and lacks the flicker of the tint change post-presentation approach. It is also completely agnostic with respect to the view hierarchy of the sub-views of the UIAlertController.
Happy hacking!