UIAlertView with 3 textfields and 3 labels overlap each other - ios

I'm trying to create an UIAlertView with 3 TextFields and 3 Labels.
But with my current code they just go over each other, I've tried to change the frame of the AlertView and I've tried to use the CGAffineTransform but they both didn't work.
Here's my code:
UIAlertView *myAlertView = [[UIAlertView alloc] initWithTitle:#"Sign in" message:#"\n\n\n\n\n" delegate:self cancelButtonTitle:#"Stop" otherButtonTitles:#"Sign in",nil];
UILabel *customerIdLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 55, 65, 21)];
customerIdLabel.tag =1;
customerIdLabel.text = #"Customer id: ";
[myAlertView customerIdLabel];
UITextField *customerIdField = [[UITextField alloc] initWithFrame:CGRectMake(89, 50, 160, 30)];
customerIdField.tag = 2;
customerIdField.placeholder = #"Fill in your customer id";
[myAlertView customerIdField];
And then there's two more combinations of those.
Here's the transform that I've tried:
CGAffineTransform myTransform = CGAffineTransformMakeScale(1.0, 0.5f);
[myAlertView setTransform:myTransform];
And this is what I get:

I'm pretty sure you aren't supposed to use UIAlertViews like that. You're supposed to set the title, message, etc and use the [alertview show]. The documentation seems to be pretty clear that it is an as-is class.The UIAlertViewStyle may be something you can look at, but the options are 1 text field, 1 secure field, or a username and password field.
Your best option is to use a new UIViewController and use the presentViewController:animated:completion: call.

I get around this by not changing UIAlertView but add a clear view on top of it when it is showing (you can pad with spaces) and add the textfields there at the correct location (note when rotation occurs). Then, let the tap go through the view to the UIAlertView. This has gone through Apple in 3 apps in the store.

Before the new SDK in xcode 5 you where able to add subviews to an alert view but that doesn't work anymore. I had to update an app because of that nasty code. Is better to use uipopovercontroller for ipad or show a UIView or even present a viewcontroller for either ipad or iphone.

Related

Adding UItextField and UITextView to an UIAlertView

I have this code for showing alert view with two needed extra objects:
- (void)leaveCommentButtonPressed
{
UIAlertView *leaveCommentAlert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Leave comment", nil)
message:#""
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Done", nil];
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 100, 33)];
[textField setBackgroundColor:[UIColor lightGrayColor]];
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 33, 100, 67)];
[textView setBackgroundColor:[UIColor darkGrayColor]];
[view addSubview:textField];
[view addSubview:textView];
CGFloat system_version = [[[UIDevice currentDevice] systemVersion] floatValue];
if (system_version < 7.0) //For Backward compatibility
{
[leaveCommentAlert addSubview:view];
}
else
{
[leaveCommentAlert setValue:view forKey:#"accessoryView"];
}
[leaveCommentAlert show];
}
But my problem is that I can't calculate width of alertView to set width for my text view and text field.
Maybe there are some other answers how to achieve text field and text view. But my idea is to have UIView with appropriate size.
Hic sunt dracones
Subclassing Notes
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.
You should use a alert view replacement. There are numerous in the web, for example: CXAlertView, DLAlertView or SDAlertView
If you're just looking to use a default implementation of UIAlertView, the Apple Docs also state:
Optionally, an alert can contain one or two text fields, one of which can be a secure text-input field. You add text fields to an alert after it is created by setting its alertViewStyle property to one of the styles specified by the UIAlertViewStyle constants. The alert view styles can specify no text field (the default style), one plain text field, one secure text field (which displays a bullet character as each character is typed), or two text fields (one plain and one secure) to accommodate a login identifier and password
See Alert Views
But, as mentioned in a different post, UIAlertView is deprecated and replaced by UIAlertController. Fortunately it comes with addTextFieldWithConfigurationHandler: that allows you to do what you're looking for.

UIAlertView addSubview in iOS7

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.
Here is a project on Github to add any UIView to an UIAlertView-looking dialog on iOS7.
(Copied from this StackOverflow thread.)
It took me only 1 day to create my own alert view that looks exactly like Apple's
Take a screenshot of Apple's alert for reference (font sizes, spacings, width)
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).
Implement all the methods from UIAlertView on your custom alert.
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).
Blurred background - use Apple's sample code (I used opaque white)
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
}];
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.
(source: github.io)
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 :)
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];
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.
You can find simple solution without extra classes here
It is based on setting accessoryView for ordinary UIAlertView.
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

iOS alert banner/label?

I apologize if this question is very basic. I have been googling around but can't seem to find the api/reference for a drop down alert banner/label (I do not know the proper term for this), therefore I am posting here.
This: The label/banner which has "Please enter valid email address" in it.
So here a my questions:
What is the proper term for this (alert banner? notification? label?)
I am trying accomplish similar functionality to what is shown in the image, so basically if any field is invalid, the "label/banner" expands from underneath the navigation bar with the message in it:
If this is just a UILabel, what is the simplest way of adding the expand animation?
If it is something built in, since I have seen bunch of apps do it for alerting, please let me know what its called.
Have a look here, I'm sure you will be able to find something to suite your needs.
The basic idea is that its simply a UIView that you animate down from the top of the screen (at the very basic). You can get a lot fancier by adding gradients, touch recognizers to dismiss it, etc. But pretty much to get the base line functionality you would just do something like this:
//Create a view to hold the label and add images or whatever, place it off screen at -100
UIView *alertview = [[UIView alloc] initWithFrame:CGRectMake(0, -100, CGRectGetWidth(self.view.bounds), 100)];
//Create a label to display the message and add it to the alertView
UILabel *theMessage = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(alertview.bounds), CGRectGetHeight(alertview.bounds))];
theMessage.text = #"I'm an alert";
[alertview addSubview:theMessage];
//Add the alertView to your view
[self.view addSubview:alertview];
//Create the ending frame or where you want it to end up on screen, in this case 0 y origin
CGRect newFrm = alertview.frame;
newFrm.origin.y = 0;
//Animate it in
[UIView animateWithDuration:2.0f animations:^{
alertview.frame = newFrm;
}];
Check out my project - it might be just the thing you're looking for.
https://github.com/alobi/ALAlertBanner
For easier control over animating the alert, you can embed your custom view in a UIStackView and simply show/hide it in an animation block. That way will significantly reduce the amount of code needed to animate the visibility of the alert.

How do I move down the buttons in UIAlertView?

I have three buttons and a textview in uialertview, and tried to move down the buttons with add "\n" in uialertview's message property. But it's not work. The string will become "..." when it reach the limit of a line. the textview always cover my buttons. Do you have any suggestions? Sorry that I don't have the right to post image.
- (void)addMessage
{
self.addMessageAlertView = [[UIAlertView alloc] initWithTitle:#"Add Title"
message:#"\n\n\n\n function normal function normal function normal function normal function normal "
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"OK",#"Search", nil];
self.addMessageTextView = [[UITextView alloc] initWithFrame:CGRectMake(10.0, 75, 260.0, 25*2)];
[addMessageTextView setBackgroundColor:[UIColor whiteColor]];
addMessageTextView.font = [UIFont systemFontOfSize:20];
addMessageTextView.delegate=self;
addMessageTextView.layer.masksToBounds=YES;
addMessageTextView.layer.cornerRadius=10.0;
addMessageTextView.layer.borderWidth=0.0;
[addMessageAlertView addSubview:addMessageTextView];
[addMessageAlertView show];
[addMessageAlertView release];
[addMessageTextView release];
}
- (void)willPresentAlertView:(UIAlertView *)openURLAlert
{
[openURLAlert setFrame:CGRectMake( 10, 60, 300, 300 )];
[openURLAlert setBounds:CGRectMake(0, 10, 290, 290 )];
}
UIAlert view has maximum height (I've tried this same thing with no success); you won't be able to make it bigger. I suggest that you use a custom pop-over instead. A popover can act like an alert but will give you more flexibility.
This question has some links to tutorials: Are there examples of how to use UIPopoverController on iOS?

ActionSheet not showing properly

I have this code to get NSStrings from an NSDictionary from an NSMutableArray but the problem is that it does not show right.
Here is the code:
UIActionSheet *playingSheet = [[UIActionSheet alloc] initWithTitle:#"Hi" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
for(NSDictionary *dict in accounts) {
NSString *name = [dict objectForKey:#"Name"];
[playingSheet addButtonWithTitle:name];
}
[playingSheet showInView:self.view];
[playingSheet release];
The problem is in my case, self.view is a subview of a parentView and is loaded from an XIB and is not full screen. So the problem is my action sheet is like half the width of the iPhone's screen and it is not even touching the bottom of the screen.
In my case, how would I fix it so its the top most view (so users can see it properly), and the way a regular actionSheet is supposed to look?
Thanks!
Edit: This was the fix:
[playingSheet showInView:[UIApplication sharedApplication].keyWindow];
You need to set the frame of the action sheet as
[playingSheet setFrame:CGRectMake(0, theHeightYouWant, 320, yourDesiredHeight)];
"theHeightYouWant" is the height by which you must shift the action-sheet upwards/downwards to put it in the right position on the screen. You can change this by trial and error. For example, if your self.view is in the lower half of the screen, "theHeightYouWant" will be negative!
Depending how your code is set up, you could try using self.parentViewController.view, self.view.window, self.view.superview, or any of a variety of things. You need to provide more information if you want a more detailed answer.

Resources