67

Adding some controls to UIAlertView was deprecated in iOS7 using addSubview method. As I know Apple promised to add contentView property.

iOS 7 is released now and I see that this property is not added. That is why I search for some custom solution with ability to add progress bar to this alertView. Something for example similar to TSAlertView, but more ready for using in iOS 7.

B.S.
  • 21,660
  • 14
  • 87
  • 109
  • 3
    The GM seed is released, not the public release. Test and raise bug reports with Apple if required. – Wain Sep 10 '13 at 21:43
  • 9
    @Jeremy As has been pointed out many times here on SO, iOS 7 questions are not off-topic. Of course no dev should discuss stuff covered by the NDA they agreed to. But SO specifically does not care. – rmaddy Sep 10 '13 at 21:52
  • 1
    altering UIAlertView's view hierarchy is explicitly forbidden for quite a while now. *"The UIAlertView class is intended to be used as-is and does not support subclassing. The view hierarchy for this class is private and must not be modified."* – vikingosegundo Sep 14 '13 at 18:30
  • possible duplicate of [Alert view is showing white rectangle in iOS7](http://stackoverflow.com/questions/18895106/alert-view-is-showing-white-rectangle-in-ios7) – Abizern Sep 23 '13 at 11:26
  • Do you have any links to any documentation about Apple's decisions on this? I can't see the reference to addSubview being removed in the iOS 7 API Diff document – Keab42 Sep 25 '13 at 11:32
  • There are no links or words in UIAlertView documentation. Only fact that it doesn't work in iOS7 and a lot of discussions on Apple's DevForums – B.S. Sep 25 '13 at 11:47
  • If you need only one textfield or a login-dialog see [my answer for a login dialog][1] [1]: http://stackoverflow.com/a/19051713/993494 – Thorsten Niehues Sep 27 '13 at 13:18
  • As an alternative to the desired contentView one could set the value of the "accessoryView" key to a custom view in iOS7 (only available in iOS7 and not backwards compatible) and thus achieve the same result as adding a subview. For more info, see this SO answer: http://stackoverflow.com/questions/18759206/how-to-add-subview-inside-uialertview-for-ios-7 – schmittsfn Mar 06 '14 at 16:03
  • 1
    from iOS8 use UIAlertController instead – János Jul 20 '14 at 15:33
  • Just working as charm http://stackoverflow.com/a/25175893/2459296 – MD SHAHIDUL ISLAM Aug 07 '14 at 06:50

8 Answers8

55

Here is a project on Github to add any UIView to an UIAlertView-looking dialog on iOS7.

(Copied from this StackOverflow thread.)

Custom iOS7 AlertView dialog

Community
  • 1
  • 1
Wimagguc
  • 1,001
  • 1
  • 7
  • 12
  • +1 for the Great job dude, I will update my answer to add your awesome control. – Tarek Hallak Oct 08 '13 at 19:21
  • Another fork with another design here : [github.com/kwent/ios-custom-alertview](https://github.com/kwent/ios-custom-alertview). – Quentin Rousseau Oct 31 '13 at 20:15
  • This does not work with ARC disabled. Just spent most of my afternoon trying to fix the original github project but to no avail. – Wedge Martin Nov 06 '13 at 02:08
  • 3
    Thank @WedgeMartin; it's true, this project is an ARC one. However, you don't need to *fix* the original, just set an exception in Xcode: http://stackoverflow.com/questions/10523816/how-to-enable-arc-for-a-single-file – Wimagguc Nov 07 '13 at 15:15
  • @Wimagguc I have implement this library . One think I am unbale to solve . How can I access the view property like uiview , uibutton from this custom alertview ? – Shourob Datta May 01 '18 at 17:08
35

It took me only 1 day to create my own alert view that looks exactly like Apple's

  1. Take a screenshot of Apple's alert for reference (font sizes, spacings, width)
  2. Create a xib with title, message, custom view and tables for buttons (Apple uses tables instead of UIButton now, default table cell is good enough). Note you need 3 button tables: two for left and right buttons (whenever the number of buttons is 2), another one for the other cases (one button or more than 2 buttons).
  3. Implement all the methods from UIAlertView on your custom alert.

  4. Show/Dismiss - you can create a specific modal window for your alerts but I just put my alerts on top of my root view controller. Register your visible alerts to a static array. If showing the first alert/dismissing the last, change tint mode of your window/view controller to dimmed/to automatic and add/remove a dimming view (black with alpha = 0.2).

  5. Blurred background - use Apple's sample code (I used opaque white)
  6. 3D dynamic effects - use Apple's sample code (5 lines of code). If you want a nice effect, take a slightly bigger snapshot in step 5 and add inverse animators for alert background and foreground.

EDIT:

Both blurred background and the paralax effect sample code can be found in "iOS_RunningWithASnap" WWDC 2013 sample code

Paralax effect:

UIInterpolatingMotionEffect* xAxis = [[[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x"
                                                                                     type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis] autorelease];
xAxis.minimumRelativeValue = [NSNumber numberWithFloat:-10.0];
xAxis.maximumRelativeValue = [NSNumber numberWithFloat:10.0];

UIInterpolatingMotionEffect* yAxis = [[[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y"
                                                                                     type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis] autorelease];
yAxis.minimumRelativeValue = [NSNumber numberWithFloat:-10.0];
yAxis.maximumRelativeValue = [NSNumber numberWithFloat:10.0];

UIMotionEffectGroup *group = [[[UIMotionEffectGroup alloc] init] autorelease];
group.motionEffects = @[xAxis, yAxis];
[self addMotionEffect:group];

The blurred background is the only complicated thing. If you can use an opaque color instead, use it. Otherwise it's a lot of experimenting. Also note that blurred background is not a good solution when the background is dark.

For the show/dismiss animationg, I am using the new spring animation method:

void (^animations)() = ^{
    self.alpha = 1.0f;
    self.transform = CGAffineTransformIdentity;
};

self.alpha = 0.0f;
self.transform = CGAffineTransformMakeScale(0.5f, 0.5f);

[UIView animateWithDuration:0.3
                      delay:0.0
     usingSpringWithDamping:0.7f
      initialSpringVelocity:0.0f
                    options:UIViewAnimationOptionCurveLinear
                 animations:animations
                 completion:^(BOOL completed) {
                         //calling UIAlertViewDelegate method
                     }];
Sulthan
  • 128,090
  • 22
  • 218
  • 270
  • @Sulthan Could you tell me wich WWDC video or sample is using the 3d/parallax effect? thanks. andrea – Andrea Sep 20 '13 at 08:15
  • Well i found this to be very helpful. They gave you everything needed to perform such an action, with options for extra abilities, i say good job! – user2277872 Oct 02 '13 at 13:05
  • 14
    George Asda: Sulthan kindly provided a high-level checklist of what to cover when creating a UIAlertView clone. Also, showed integrity as an employee by not directly sharing code that someone else has paid for. He didn't have to help at all. Show some respect. Better still, create an implementation and share it with us... do unto others etc. – Chris Hatton Nov 11 '13 at 17:53
32

I wrote a full implementation of UIAlertView that mimics the complete UIAlertView API, but adds the contentView property we've all wanted for so long: SDCAlertView.

image
(source: github.io)

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Scott Berrevoets
  • 16,921
  • 6
  • 59
  • 80
  • @GeorgeAsda: What kind of "package" were you thinking about? – Scott Berrevoets Dec 29 '13 at 19:12
  • more like a list of the files someone needs to get this working on their project without the cocoa pods cr@p (that is my humble opinion). BTW there is a "bug" on this.. when you try to add a uitextview it is unresponsive (i think it's added "below" some other view and touches are not detected..) – George Asda Dec 29 '13 at 20:38
  • 2
    @GeorgeAsda: As for your bug: please ask a separate question and add the appropriate information and code. The README indicates which files the project needs to build correctly. Not sure what you have against Cocoapods, but many people consider it the easiest way of getting the most up to date files for this project. – Scott Berrevoets Dec 29 '13 at 21:32
  • 1
    I consider it a big negative against a library if it doesn't support cocoapods, and greatly prefer it over some other, much more manual method of adding a third party library. But for anyone who doesn't like it, they can always take the hard path if they choose. – Gavin Jan 13 '14 at 17:37
  • @GeorgeAsda I cannot agree with you more. I was JUST thinking the same thing! More and more projects are trying to force the developer to use pods! Its a great project but I don't wanna use pods to every project I do! How hard is it to create a demo project without forcing the developer to install cocoapods, right? – Isuru Jan 27 '14 at 15:29
  • @Gavin It's totally fine if a project supports cocoapods. I just think its better if devs wouldn't use pods in the demo project they include with the library so that the people who don't like using pods can easily check it out. – Isuru Jan 27 '14 at 15:34
  • Well you could add them to your demo project manually. Let developers who download your project worry about updates on those dependencies. Create two demos. That's what I would do anyway... What if one of those dependencies get updated and breaks your project???? – George Asda Jan 27 '14 at 16:57
  • That's not a bad idea. If you can create an issue for it that'd be great, I'm afraid I may forget otherwise. – Scott Berrevoets Jan 28 '14 at 04:42
  • 5
    Pods are definitely the way to go. Ignore the naysayers. If they don't want to use Pods it is simple enough to add it manually, I'm shocked at how rude the anti-pod crowd is. – powerj1984 Apr 23 '14 at 17:04
  • 1
    @GeorgeAsda "What if one of those dependencies get updated and breaks your project????" With cocoapods you can define the version of your dependency and "freeze" it there. On the other hand it is not always so easy with manually copying files to tell exactly which version you need. – Kremk Sep 17 '14 at 23:41
  • 1
    @Kremk all i say is that I want to be in charge of what i download and not some bloody pod.... You don't have to agree with me. You just have to accept a different point of view. – George Asda Sep 18 '14 at 21:41
27

For those who love simple and effective methods with out having to write lines of code. Here is a cool solution without using any other private frame works for adding subviews to ios 7 alert views,i.e.

[alertView setValue:imageView forKey:@"accessoryView"];

Sample code for better understanding,

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(180, 10, 85, 50)];
UIImage *wonImage = [UIImage imageNamed:@"image.png"];
[imageView setImage:wonImage];

//check if os version is 7 or above
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
      [alertView setValue:imageView forKey:@"accessoryView"];
}else{
      [alertView addSubview:imageView];
}

Hope it helps some one,thanks :)

Eshwar Chaitanya
  • 942
  • 2
  • 13
  • 34
  • 3
    I request the down voter to kindly review the answer carefully and think twice before voting down. At least provide reason in comment is min. criteria :v – Eshwar Chaitanya May 30 '14 at 04:19
  • Not working. It is working without iOS 7 that means `else` condition is working fine with `addSubview` but `if` condition is not working with `setValue`. – MD SHAHIDUL ISLAM Aug 07 '14 at 06:07
  • @Salim Please check your Xcode version, ios 7 is available on Xcode with version of 5 and above – Eshwar Chaitanya Aug 07 '14 at 07:31
  • 1
    Awesome answer. Worked like a charm for me for adding a UIActivityIndicatorView to the UIAlertView. I just changed the UIImageView with the activity indicator – Septronic Aug 29 '14 at 18:56
  • The image size is ignored. Can't understand why. – bruno Mar 17 '15 at 14:22
17

For IOS7

UIAlertView *alertView1 = [[UIAlertView alloc] initWithTitle:@"Enter Form Name" 
                                               message:@""
                                               delegate:self 
                                               cancelButtonTitle:@"Cancel"
                                               otherButtonTitles:@"Ok", nil];
alertView1.alertViewStyle = UIAlertViewStyleSecureTextInput;
UITextField *myTextField = [alertView1 textFieldAtIndex:0];
[alertView1 setTag:555];
myTextField.keyboardType=UIKeyboardTypeAlphabet;

[alertView1 show];
MD SHAHIDUL ISLAM
  • 14,325
  • 6
  • 82
  • 89
Ganesh manoj
  • 249
  • 1
  • 7
10

There wont be UIAlertView with custom views in iOS7, nor contentView which Apple changed its mind about, so addSubview is impossible now in UIAlertView.

A good alternative will be SVProgressHUD, according to many threads in Apple's forum.

Edit:

There is officially no addSubview nor subclassing for UIAlertView in iOS7.

The UIAlertView class is intended to be used as-is and does not support subclassing. The view hierarchy for this class is private and must not be modified.

Other good alternatives:

ios-custom-alertview by wimagguc

MZFormSheetController.

Tarek Hallak
  • 18,422
  • 7
  • 59
  • 68
1

You can find simple solution without extra classes here

It is based on setting accessoryView for ordinary UIAlertView.

Community
  • 1
  • 1
malex
  • 9,874
  • 3
  • 56
  • 77
1

PKAlertController (https://github.com/goodpatch/PKAlertController) is great library. I tested a lot of similar libraries and just this satisfied all my requirements.

Why it is cool:

  • Supports custom view
  • Supports iOS7
  • It is view controller
  • It behaves and looks like native alert view, including motion effects
  • Customizable
  • Similar interface like in UIAlertController
Igor Palaguta
  • 3,579
  • 2
  • 20
  • 32