17

I am used to customize UIAlertViews through the [alert setValue:someView forKey:@"accessoryView"] method. This creates customizable content for UIAlertViews with custom heights. However it only works on iOS7 and down. In iOS8 the UIAlertController have taken over, and I cannot customize it anymore, it will cut the height of the UIAlertView.

Is it impossible because of misuse of the UIAlertController, or how am I supposed to do it? I am trying to incorporate a UITableView inside a UIAlertController with UIAlertControllerStyleAlert.

Thx.

kbjeppesen
  • 335
  • 1
  • 3
  • 9
  • I ended up using this library instead https://github.com/wimagguc/ios-custom-alertview, and abandoned the UIAlertController. – kbjeppesen Jan 14 '15 at 19:35

4 Answers4

36

I ran into the same issue right now. I looked at the private header for UIAlertController (https://github.com/nst/iOS-Runtime-Headers/blob/master/Frameworks/UIKit.framework/UIAlertController.h) and found a promising property: contentViewController

And it turned out to be exactly the same as accessoryView used to be for UIAlertView, the difference being that you need to assign a UIViewController to this property rather than a UIView.

UIViewController *v = [[UIViewController alloc] init];
v.view.backgroundColor = [UIColor redColor];

[alertController setValue:v forKey:@"contentViewController"];

That piece of code will show a red view on the alert view! Happy UIAlertController customizing ;)

PS. It is a private property but using KVC there shouldn't be a problem App Store wise, I think.

Edit:

Some people complained that this isn't very safe. It's not a public API, so yes, Apple could change it in any release, causing this method to fail.

To make sure your entire app doesn't crash if that happens you could wrap the KVC call in a try block. If the property changes your controller won't show the content view, but it also won't crash:

@try {
    [alertController setValue:v forKey:@"contentViewController"];
}
@catch(NSException *exception) {
    NSLog(@"Failed setting content view controller: %@", exception);
}

Using this method in production can be risky, and I don't recommend it for important alerts.

JonasG
  • 9,274
  • 12
  • 59
  • 88
  • How can you adjust the height of the alertcontroller using this method? – kbjeppesen Jan 14 '15 at 19:34
  • 1
    You can override `-preferredContentSize` to return a custom size in the view controller that you are setting as `contentViewController`. – JonasG Jan 14 '15 at 20:02
  • Can anyone confirm that this has been accepted by the app store? – Josh Valdivieso Feb 24 '15 at 20:40
  • Yes, I'm using this method and it has been accepted. – JonasG Feb 24 '15 at 20:41
  • Is it allowed by Apple? or Is it depend on reviewer? I just wanna make sure before I use it. – Dae KIM Feb 25 '15 at 23:24
  • 1
    Like I said in the answer, because you're assigning it via KVO it can't and won't be detected by Apple's static analyzer and so it will pass the reviewing process. – JonasG Feb 25 '15 at 23:32
  • Works on iOS 9 too. Amazing! – Rudolf Adamkovič Aug 07 '15 at 20:13
  • Just discovered: `UIAlertAction` also has `contentViewController` property. – Rudolf Adamkovič Aug 07 '15 at 21:16
  • @RudolfAdamkovic true, interesting! – JonasG Aug 07 '15 at 22:03
  • 11
    We did something similar using KVO to access the `_buttons` on a `UIAlertView` a few years ago. Then they changed the name of the identifier and all our IAPs stopped working on iOS 8. Not a fun few days rushing out fixes for 20 apps. I heavily advise ***against*** this solution – James Webster Oct 09 '15 at 07:56
  • 3
    Question is what do you *strongly* suggest instead? – Alex Sorokoletov Oct 23 '15 at 07:05
  • 1
    I suggest not bothering to shoehorn this functionality into the native alert. Many people have gone and replicated the native alerts, producing near perfect replicas that handle all of the rotation/size/interaction edge cases. I've had success with SDCAlertView @ https://github.com/sberrevoets/SDCAlertView – Adam Kaplan Oct 31 '15 at 18:55
  • Whether you found a trick to get around the Apple review or not, you just really shouldn't be accessing and relying on private Apple properties. I completely agree with Adam Kaplan on this, and James Webster's experience should be a good warning against this practice as well. – Erik van der Neut Mar 08 '16 at 06:30
  • @Erik Whether it's a good practice to use this in the App Store or not, it answers the question. The question didn't ask for a public API (the example in the question is even a private property). If you want to use this method or not doesn't change the fact that this is exactly what the question asked for. – JonasG Mar 08 '16 at 11:58
  • It would be irresponsible NOT to point out the drawbacks of that approach. And the onus is not be on the person asking the question to say "and don't suggest anything that will get me In trouble later on" every time..That should be assumed. – Peter Johnson Feb 19 '17 at 09:57
  • @PeterJohnson in the question he says he is already using the KVC method for UIAlertView. The whole point of the question was to find out how to set custom a view using KVC for UIAlertController. If there was a public API for it, the question wouldn't exist. The whole premise of the question is that there is no public API to set a custom view. – JonasG Feb 19 '17 at 12:11
  • Fair enough. I think I will probably go grab a customisable controller from Cocoa Controls – Peter Johnson Feb 19 '17 at 13:06
12

I suggest not your wasting time trying to cram additional UI into a place where isn't supposed to be. Based on the last few years of improvements, Apple will probably add a custom view in the next iOS. Until then, have a look at a framework designed to handle this exact situation without subverting any best practices: SDCAlertView

It supports alerts that imitate the native alerts on iOS 7,8,9, including handling all of the nasty edge cases around sizing, button types, rotation, etc. It does support arbitrary custom views within the alert.

SDCAlertView demo gif

I use this library in Yahoo YMPromptKit for custom push notification prompts that look exactly like iOS native. Here's another example:

enter image description here

Jagat Dave
  • 1,643
  • 3
  • 23
  • 30
Adam Kaplan
  • 1,954
  • 17
  • 16
2

I think you can easily customize the UIView adding the controls needed and present it modally, unless you have any other specific reason to use only UIAlertController.

https://www.cocoacontrols.com/search?q=UIAlertview

Nick
  • 2,735
  • 1
  • 29
  • 36
CyberInfo
  • 240
  • 2
  • 9
1

You can do it with just a one of line of code using my UIAlertController category and replace existing alerts in application, check it here.

enter image description here

Jagat Dave
  • 1,643
  • 3
  • 23
  • 30
Michal Zaborowski
  • 5,039
  • 36
  • 35