Alert view is showing white rectangle in iOS7 - ios

The following code works perfectly from iOS 5 to 6.1. I even have applications in store with that code:
-(void)showActivityIndicator
{
if(!mLoadingView) //
{
mLoadingView = [[UIAlertView alloc] initWithTitle:#"" message:#"" delegate:self cancelButtonTitle:nil otherButtonTitles:nil];
mLoadingView.tag = kAlertViewTag;
}
[mLoadingView show];
}
- (void)willPresentAlertView:(UIAlertView *)alertView
{
if (alertView.tag == kAlertViewTag)
{
UIActivityIndicatorView *actInd = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
actInd.frame = CGRectMake(128.0f, 45.0f, 25.0f, 25.0f);
[alertView addSubview:actInd];
[actInd startAnimating];
UILabel *l = [[UILabel alloc]init];
l.text = NSLocalizedString(#"PRODUCT_PURCHASE_INDICATOR_TITLE", #"Please wait...");
l.font = [UIFont fontWithName:#"Helvetica" size:16];
float strWidth = [l.text sizeWithFont:l.font].width;
float frameWidth = alertView.frame.size.width;
l.frame = CGRectMake((frameWidth - strWidth)/2, -25, 210, 100);
l.textColor = [UIColor whiteColor];
l.shadowColor = [UIColor blackColor];
l.shadowOffset = CGSizeMake(1.0, 1.0);
l.backgroundColor = [UIColor clearColor];
[alertView addSubview:l];
}
}
It will show alert view without buttons and with activity indicator and label. However in iOS7 I can see only white rounded rectangle, no activity indicator.
What can I do to have this work from iOS 5 to 7?
Update:
To be more descriptive I'm adding screenshots. The following is iOS 5 to 6.1 screenshot. Works fine there.
The following is iOS7. As you can see even the size is smaller. Looks like it's not fully initialized or something.

now addSubview is not available in 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
As an alternative you can use SVProgressHUD.

From iOS 7 onwards, you can do:
[alertView setValue:customContentView forKey:#"accessoryView"];
to get custom content in a standard alert view.

I had to fix this problem very quickly, hence I have built an iOS7 UIAlertView-style UIView with its animations, which can be extended with any custom content.
There might be others who can use my solution, so I made the whole code available on Github.
Also, if you want to keep using the UIAlertView under previous OS versions, you have to fork the code. It might be as bad as it sounds, I'm using the following:
float sysVer = [[[UIDevice currentDevice] systemVersion] floatValue];
if (sysVer < 7) {
// your old solution
} else {
.. // iOS7 dialog code
}
(Please be aware that this is by no means a real solution - if Apple doesn't want us to use the dialogs for all sorts of things, then we probably shouldn't.)

Related

UITextField in UIAlertController (border, backgroundColor)

Here is a screenshot of a UIAlertController. I was just playing around custom fonts and textfield properties but I was unable to accomplish the following:
clear background of the UITextField
no ugly border (black box) as shown below
As I dived more into the code and iOS runtime headers, I was able to modify border and background color but the above issue still remains as those properties belong to a container UITextView. Changing background to clearColor doesn't help.
Has anybody ever played around with this? Not sure if I would ever take my app into production with such ugly text fields.
EDIT (May 13, 15) The answer below by Rory McKinnel is tested for iOS 8 - 8.3 and works just fine. The result is below:
Had some fun with this. The following seems to work. Obviously judging by what was required, it has no future proofing and is a patch away from not working.
I figured this out by walking the view hierarchy in the debugger, from which I noticed a UIVisualEffectView. Removing that seems to give you what you want along with setting the containing view to a clear background. Without removing the visual effect, a clear background shows what is behind the alert view itself for some reason.
UIAlertController *alertController =
[UIAlertController alertControllerWithTitle:#"Its Not Pretty!"
message:#"Some times things get ugly!"
preferredStyle:UIAlertControllerStyleAlert];
[alertController addTextFieldWithConfigurationHandler:^(UITextField *textField){
textField.text = #"Text: No border and clear 8^)";
}];
[self presentViewController:alertController animated:TRUE completion:^{
}];
for (UIView* textfield in alertController.textfields) {
UIView *container = textField.superview;
UIView *effectView = container.superview.subviews[0];
if (effectView && [effectView class] == [UIVisualEffectView class]){
container.backgroundColor = [UIColor clearColor];
[effectView removeFromSuperview];
}
}
here is the important part in swift:
for textfield: UIView in alertController.textfields {
var container: UIView = textField.superview
var effectView: UIView = container.superview.subviews[0]
container.backgroundColor = UIColor.clearColor()
effectView.removeFromSuperview()
}
Swift 3 clear version
alertController.textFields?.forEach {
$0.superview?.backgroundColor = .clear
$0.superview?.superview?.subviews[0].removeFromSuperview()
}
You can try this.
As you need only clear color to textfield of your alertview.
simply add lines of code after your alertview is created.
UITextField *textField = [alertView textFieldAtIndex:0];
textField.backgroundColor=[UIColor clearColor];
textField.superview.backgroundColor=[UIColor clearColor];
EDIT
for alertviewCoontroller you can add
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.backgroundColor=[UIColor clearColor];
textField.superview.backgroundColor=[UIColor clearColor];
}];
Thanks, revert if any confusion.
You can change the border and background color like this:
let subview = alertController!.view.subviews.first! as UIView
let alertContentView = subview.subviews.first! as UIView
alertContentView.backgroundColor = UIColor.lightGrayColor()
alertContentView.layer.cornerRadius = 10;
alertContentView.layer.borderWidth = 2;
Swift 2.0 version:
for textField in alert.textFields! {
if let container = textField.superview, let effectView = container.superview?.subviews.first where effectView is UIVisualEffectView {
container.backgroundColor = UIColor.clearColor()
effectView.removeFromSuperview()
}
}
To address the situation as discussed in #Rory McKinnel and #Matthew where the superview are NULL and address modifying presented view:
extension UIAlertController {
override open func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.textFields?.forEach {
$0.superview?.backgroundColor = .color
$0.superview?.superview?.subviews[0].removeFromSuperview()
}
}
}
This is very hacky, so examine it well before using (tested on iOS 8.3):
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#"My Alert"
message:#"This is an alert."
preferredStyle:UIAlertControllerStyleAlert];
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.placeholder = #"This is my placeholder";
textField.backgroundColor = [UIColor colorWithRed:246.0/255.0 green:246.0/255.0 blue:246.0/255.0 alpha:1.0]; // You can change it to whatever color you want
[textField superview].backgroundColor = textField.backgroundColor;
[[textField superview] superview].backgroundColor = [UIColor whiteColor];
}];

Drawing a Rect on UIView

I'm trying to draw a rect on a UIView when a button is clicked, but for some reason isn't working...
- (IBAction)createNewGame:(id)sender {
[self dismissViewControllerAnimated:NO completion:nil];
//create the new game and add to the array of games, save the index of actual game.
FIALGameModel *newGame = [[FIALGameModel alloc] initWithRows:_row columns:_column];
[_games addObject:(newGame)];
_actualGame = [_games count]-1;
if(_debug==true) {
NSString* messageString = [NSString stringWithFormat: #"Creating a New Game with %d rows and %d columns.", _row, _column];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Alert"
message: messageString
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
UIView *test = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 60, 60)];
test.backgroundColor = [UIColor redColor];
[_areaGame addSubview:test];
}
The alert works fine, but the rect don't.
As #matt hints in comment, the most usual cause of this is that you've not bound your properties or fields to your UI components properly, or else you've tried to run this code before the UIView was loaded. In either case, _areaGame is nil and the addSubview call silently does nothing. Setting a breakpoint on the addSubview line and inspecting _areaGame is the quickest way to verify.

Add UISlider on UIAlertView

I want to add a UISlider on a UIAlerView but I am not able to do that. I also google that but I found only two answers and both of them are not showing any any result here is code what I found and applied in my project:
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"title" message:#"msg" delegate:self cancelButtonTitle:#"cancel" otherButtonTitles:#"ok", nil];
alertView.title = #"title";
CGRect frame = CGRectMake(alertView.frame.origin.x+10,alertView.frame.origin.y+20,100, 100.0);
UISlider *slider = [[UISlider alloc] initWithFrame:frame];
[slider addTarget:self action:#selector(sliderAction:) forControlEvents:UIControlEventValueChanged];
[slider setBackgroundColor:[UIColor clearColor]];
slider.minimumValue = 0.0;
slider.maximumValue = 10.0;
slider.continuous = YES;
slider.value = 25.0;
[alertView addSubview:slider];
[alertView show];
I think the frame of slider is not proper thats why its not being displayed.
can anyone help me in that.....
Thank you in advance...
You are adding the Slider in Alert view not in parent view of Alert view.
So your frame value will add the slider some where wide in alert view, result will be hidden on alert view.
so replace this line
CGRect frame = CGRectMake(alertView.frame.origin.x+10,alertView.frame.origin.y+20,100, 100.0);
To
CGRect frame = CGRectMake(10,20,100, 100.0);
The UIAlertView is also a UIView. I indeed, you could add the subview in it. But Apple says
"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."
So Better to have custom view which will act as alertview.Like this one

adding a custom view to a alert view

i have a problem like this:
i want to show a customized view inside a alert view. so i create a separate xib file and designed my interface.and implemented the class for it too.but when i apply below code,it gives me an error.
this is the code :
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Confirm your Action"
message:#"Click OK to confirm"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:#"Cancel",nil];
NSArray *subviewArray = [[NSBundle mainBundle] loadNibNamed:#"customDialogViewController" owner:self options:nil];
customDialogViewController *myView = (customDialogViewController*) [subviewArray objectAtIndex:0];
[alert setValue:myView forKey:#"accessoryView"];
//alert.alertViewStyle = UIAlertViewStylePlainTextInput;
alert.tag = KAlertViewthree;
[alert show];
and this is my error :
Terminating app due to uncaught exception 'UIViewControllerHierarchyInconsistency', reason: 'child view controller:<ScheduleView: 0x8adf1a0> should have parent view controller:<_UIModalItemAccessoryViewControllerForLegacyAlert: 0xa888b70> but actual parent is:<UINavigationController: 0x8add8c0>'
i really new to iOS development.did i do this wrong ? where is the mistake ? i don't know what is this Nib file talking here "loadNibNamed:#bla boa " i just gave my xib name for that. can anyone give me a better way to do this or can you tell me the where i have to change to fix this issue ?
please guide me some one..
thank you.
This API has solution for your problem use this and have fun
https://github.com/Darktt/DTAlertView
https://github.com/Scott90/SDCAlertView
https://github.com/lmcd/LMAlertView
for all who having this problem,
i have followed this link..and for the star marks, i used this..
all you have to do is add below files to the project
CustomIOS7AlertView.h
CustomIOS7AlertView.m
JSFavStarControl.h
JSFavStarControl.m
and put below code where you want to pop up the alert view
// Here we need to pass a full frame
CustomIOS7AlertView *alertView = [[CustomIOS7AlertView alloc] init];
// Add some custom content to the alert view
[alertView setContainerView:[self createDemoView]];
// Modify the parameters
[alertView setButtonTitles:[NSMutableArray arrayWithObjects:#"Close1", #"Close2", #"Close3", nil]];
[alertView setDelegate:self];
// You may use a Block, rather than a delegate.
[alertView setOnButtonTouchUpInside:^(CustomIOS7AlertView *alertView, int buttonIndex) {
NSLog(#"Block: Button at position %d is clicked on alertView %d.", buttonIndex, [alertView tag]);
[alertView close];
}];
[alertView setUseMotionEffects:true];
// And launch the dialog
[alertView show];
and inside the method of createDemoView,you have to implement your customised view.in my case it is like this
UIView *demoView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 290, 100)];
//alertView.tag=2;
UILabel *rateLbl=[[UILabel alloc]initWithFrame:CGRectMake(10, 10, 290, 45)];
rateLbl.backgroundColor=[UIColor clearColor];
rateLbl.font=[UIFont boldSystemFontOfSize:15];
rateLbl.text=#"Rate";
UILabel *cmntLable=[[UILabel alloc]initWithFrame:CGRectMake(10, 45, 290, 45)];
cmntLable.backgroundColor=[UIColor clearColor];
cmntLable.font=[UIFont boldSystemFontOfSize:15];
cmntLable.text=#"Add Comment";
UIImage *dot, *star;
dot = [UIImage imageNamed:#"dot.png"];
star = [UIImage imageNamed:#"star.png"];
JSFavStarControl *rating = [[JSFavStarControl alloc] initWithLocation:CGPointMake(150, 20) dotImage:dot starImage:star];
[rating addTarget:self action:#selector(updateRating:) forControlEvents:UIControlEventValueChanged];
UILabel *lblAlertTItle=[[UILabel alloc]initWithFrame:CGRectMake(5, 5, 290, 45)];
lblAlertTItle.backgroundColor=[UIColor clearColor];
lblAlertTItle.textAlignment=UITextAlignmentCenter;
lblAlertTItle.font=[UIFont boldSystemFontOfSize:18];
lblAlertTItle.text=#"Choose your sharing option";
UITextField *text = [[UITextField alloc]initWithFrame:CGRectMake(150, 57, 100, 25)];
text.backgroundColor=[UIColor whiteColor];
//[demoView addSubview:lblAlertTItle];
[demoView addSubview:text];
[demoView addSubview:rating];
[demoView addSubview:rateLbl];
[demoView addSubview:cmntLable];
return demoView;
so my output is like this.
use it and have fun :)
thank you for everyone who helped me.
In to native Alert-view in ios7 that not possible to adding custom View as a sub-view of alert-view. You can use ios-custom-alertview for doing this kind of task you can do what you want. Hope this helpful to you.
I am using this ios-custom-alertview with Adding two Bellow file in to my project.
CustomIOS7AlertView.h
CustomIOS7AlertView.m
and how to use there is quick-start-guide

Change the font size of a UITextField in a UIAlertView

Does anyone know how to change the font size of a UITextField within a UIAlertView? The following is my code...
- (void) editTitle
{
NSString *string = kLocalizedString(#"Edit Title");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil
message:string
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"OK", nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
UITextField *textField = [alert textFieldAtIndex:0];
if (!self.title) {
textField.text = nil;
}
else {
textField.text = self.title;
}
textField.clearsOnBeginEditing = NO;
textField.clearButtonMode = UITextFieldViewModeAlways;
textField.autocapitalizationType = UITextAutocapitalizationTypeWords;
textField.clearsContextBeforeDrawing = NO;
// These statements have no effect on the size of the text field's font
textField.font = [UIFont systemFontOfSize:16.0];
NSDictionary *attributes = #{
NSFontAttributeName: [UIFont systemFontOfSize:16.0]};
textField.typingAttributes = attributes;
[alert show];
}
After iOS 7.x you cannot customize the appearance of alert views, Why? Because its view hierarchy is private.
It is mentioned clearly in UIAlertView Class Reference:
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.
So unfortunately it is impossible to change the textField font, buttons text color .. etc.
The only solution is using one of the custom UIAlertView's.
You have to use custom alertview. Just check below link.
DTAlertView
It has good animation and textfield can be added too.
Once you use this, you don't have to write such big code.
Hope it helps.
You can create a custom UIAlertView using one of this:
http://code.tutsplus.com/tutorials/ios-sdk-uialertview-custom-graphics--mobile-8886
https://github.com/eaigner/CODialog
and apply your custom textField.
For the second option, in CODialog.m (addTextFieldWithPlaceholder function) you can change the font size, or modify kCODialogTextFieldHeight constant.
field.font = [UIFont systemFontOfSize:kCODialogTextFieldHeight - 8.0];

Resources