Change UIAlertView with swizzling

329 Views Asked by At

I've recently been handed a private hardware SDK to integrate into my company's mobile app. Everything works great except they are using a UIAlertView as the result of some opaque method call, and my design team wants to brand this. I don't have access to the SDK's source code. Is there a way I can safely swizzle UIAlertView to preserve all functionality and simply modify the appearance of the UIAlertView so it's more branded/consistent with the app appearance? If so, would I overload drawRect or something else, and how would I figure out what the names of the labels in UIAlertView are so that I can draw them with the size, shape, and color that I want?

for added detail, the app does not currently use UIAlertView or UIAlertViewController so in theory swizzling would only affect whatever is going on with this closed-source SDK.

1

There are 1 best solutions below

2
On

That wouldn't be straightforward at all.


If the SDK is using UIAlertView, then try swizzling the show method.

Your implementation should do approximately the following:

1) Do not let the original UIAlertView to show -- it is very hard to customize it.

2) Keep reference of old .delegate to be able to notify it when needed.

3) Create your own custom UIView and use [[UIApplication sharedApplication].keyWindow addSubview:myCustomAlertView];.

4) I believe you can get all of the previous UIAlertView variables (i.e. button titles, textFields, etc), using its properties such as

@property(nonatomic,copy) NSString *title;
@property(nullable,nonatomic,copy) NSString *message;
- (nullable NSString *)buttonTitleAtIndex:(NSInteger)buttonIndex;
@property(nonatomic,readonly) NSInteger numberOfButtons;
@property(nonatomic) NSInteger cancelButtonIndex;

5) Create your own designs and call corresponding delegate methods when needed.


Other approach is to use Apple's Private API, but this may lead to bad results.

This is a VERY HACKY approach. Firstly, you have no guarantees that it would even work. Secondly, your app may be rejected. Therefore, I wouldn't really recommend it...

However, if you really want to go with this approach, then try doing this:

After [myAlertView show]; look at its properties after some delay (i.e. 0.01 sec is enough):

enter image description here

Now look for suspicious properties (probably of UIView class), which might have UI-related information. For example, __representer looks quite interesting -- it has constraints, it has labelContainerView... Try playing with those properties.

In order to get that __representer, use KVC and KVO (i.e. start with id theAlertController = [myAlertView valueForKey:@"_alertController"];). Then dive deeper and deeper.

Hopefully, you would be able to find useful properties and would be able to change their values via KVC.