I have an issue related to UIAlertView while running our app on iOS 8.
I am showing an alert with title as nil. It was working fine in iOS 7 but now UI looks odd.
I have attached screenshot here.
One solution I found is that when I provide empty string #“” it looks okay. See below screenshot. But I am not sure if the issue I mentioned is bug in beta iOS 8 version or if there is any other better solution. Even with the solution it's not exact as it was in iOS 7.
iOS 7 - showing alert view with title as nil. Screenshot here.
The closest I could get with iOS 8 was by setting the title instead of the message:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Location field required." message:nil delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
It should be noted, however, that UIAlertView is deprecated in iOS 8 and, if you're going to be using separate code paths for iOS 7 and iOS 8, you should be using UIAlertController instead:
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Location field required." message:nil preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
[self dismissViewControllerAnimated:YES completion:nil];
}]];
[self presentViewController:alert animated:YES completion:nil];
I got the same results with both methods.
It has been the best practice for me to use initWithTitle:#"" for UIAlertView, UIActionSheet since iOS 6 because I was facing a design issue during that time when I was using initWithTitle:nil. I tried to find back, I couldn't find it what exactly is the reason.
From your screen shot on iOS 8, I think there is a change of view hierarchy on UIAlertView for iOS 8. I think Auto layout might be implemented on the view hierarachy as well as you can see the messageLabel jump up to the titleLabel.
I can not be sure because the view hierarchy for UIAlertView is private.
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.
See: https://developer.apple.com/library/ios/documentation/uikit/reference/UIAlertView_Class/UIAlertView/UIAlertView.html
But, I use the code:-
NSLog(#"%#",[self.alertView description]);
Result on iOS 7.1:
<UIAlertView: 0x7fb3c05535b0; frame = (18 263; 284 62); opaque = NO; layer = <CALayer: 0x7fb3c0519810>>
Result on iOS 8.0:
<UIAlertView: 0x7bf64840; frame = (0 0; 0 0); layer = <CALayer: 0x7bf648f0>>
I am not sure why the UIAlertView frame for iOS 8 is (0 0; 0 0);
Like Mike said, I think you should learn to use UIAlertController for iOS 8.
I managed to get decent message alignment without the bold font by:
Setting the title to #"" instead of nil, and
(If IOS8) prepend a "\n" in front of the message.
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#""
message:#"\nLocation field required."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
Please try this code.
it is working on my side
xcode version 9.2
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:nil
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction* btn1 = [UIAlertAction
actionWithTitle:#"OKAY"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
}];
[self presentViewController:alert animated:YES completion:nil];
Related
what im trying to accomplish is on pressing the statusbar a alert pops up. im trying to learn tweak development and the tutorial im following is a bit old and uses the deprecated UIAlertView So after finding the correct header (UIAlertController) i get the following errors trying to compile the tweak. Sry if this is a noob question i googled and nowhere really gave a clear answer for it. thanks in advance.
code-
#include <UIKit/UIKit.h>
%hook SBStatusBarManager
-(void)handleStatusBarTapWithEvent:(id)arg1{
UIAlertController *alert = [[UIAlertController alloc] alertControllerWithTitle:#"My Alert" message:#"I hope this works!" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {}];
[alert addAction:defaultAction];
[self presentViewController:alert animated:YES completion:nil];
%orig;
}
%end
Here are the errors i got trying to compile.
Tweak.x:9:55: error: no visible #interface for 'UIAlertController' declares the selector 'alertControllerWithTitle:message:preferredStyle:'
Tweak.x:13:7: error: no visible #interface for 'SBStatusBarManager' declares the selector 'presentViewController:animated:completion:'
Firstly:
alertControllerWithTitle:message:preferredStyle is a class method, so you cannot call it on an instance.
This should work:
UIAlertController* alertController = [UIAlertController alertControllerWithTitle:#"My Alert"
message:#"I hope this works!"
preferredStyle:UIAlertControllerStyleAlert]
Secondly:
SBStatusBarManager is not a UIViewController, so you need to find a suitable UIViewController that can present your alert controller.
Maybe you can try to access the root view controller, this link should help: https://stackoverflow.com/a/36879892/3227743
Then, you can present the alert view controller accordingly.
I am using this code to show UIAlert which will ask simple input
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Alert" message:#"Message" preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:#"Click" style:UIAlertActionStyleDefault handler:nil]];
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.placeholder = #"Enter text:";
}];
[self presentViewController:alert animated:YES completion:nil];
Also tried this code of iOS 7
UIAlertView *alertViewCustomQuestion=[[UIAlertView alloc]initWithTitle:#"Custom Question" message:#"Please enter your custom question!" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Ok",nil];
alertViewCustomQuestion.alertViewStyle=UIAlertViewStylePlainTextInput;
[alertViewCustomQuestion show];
Both shows same result. While any example I saw has good width.
I was fixing bugs of someone's else code, Finally found there was some category that was changing its behavior.
Just adding this as a reference for someone else in the future, who might stumble upon a similar problem.
I've had a identical problem as the OP in the question above, and in my case it turned out to be PixateFreestyle framework that is being used in the project I'm working on.
Apparently the framework is not being actively developed anymore, but fortunately there is kind of a FIX for the issue.
I'm working on an old iOS app originally written for iOS 6, and it had some UIActionSheets that needed to be changed, so I've been working to move them over to UIAlertControllers, using UIAlertActions. This has worked perfectly fine on a iPad2 Simulator, however when testing on an iPad Air (the only iPad I have access to) my UIAlertAction, and UIAlertController become nil directly after being created (looked at in the debugger, it receives a pointer on creation, however as soon as it executes the next line it becomes null). Here's a code sample:
//When hovering over the next line, alert has a pointer
UIAlertController* alert = [UIAlertController
alertControllerWithTitle:#"info"
message:#"testmessage"
preferredStyle:UIAlertControllerStyleActionSheet];
//alert pointer is now nil
//test pointer shows up
UIAlertAction* test= [UIAlertAction
actionWithTitle:#"I'm a Button"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action){
[alert dismissViewControllerAnimated: YES completion:nil];
}
];
//test pointer is nil, test2 pointer exists
UIAlertAction* test2 = [UIAlertAction
actionWithTitle:#"I'm a Button"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action){
[alert dismissViewControllerAnimated: YES completion:nil];
}
];
//test2 pointer is nil
[alert addAction:test];
[self presentViewController:alert animated:YES completion:nil]; //app crashes, because I'm trying to present a nil modal.
Any thoughts or help would be much appreaciated!
UIAlertController is for iOS8 upwards. Use UIAlertView and UIActionSheet for prior to iOS8
You are best to check wether your device responds to the class,
if ([UIAlertController class]) {
// use UIAlertController for the action sheets as you have already posted
// For all operating systems (like iOS8 upwards) will land in here.
} else {
// use UIActionSheet - like you already used for iOS6
}
It's not wise to check the operating system deployment number, like if 8.0 etc, checking the if it responds to the class is the proper way to do it.
It prevents a crash means you're not relying on float numbers which are not guaranteed to be reliable, as if they change the way the operating systems is named in future, your code would crash.
I wanted to use UIAlertView to show photo. I´m using code as below for showing the alert, however it doesn't work. It shows the title, some space and button OK nothing more. I have no idea if I´m doing something wrong, because I´m new in iOS.
-(IBAction)ButtonPressed:(id)sender
{
UIAlertView *av = [[UIAlertView alloc] initWithTitle:#"titel"
message:nil
delegate:nil //or self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(180, 10, 85, 50)];
[imageView setImage:#"dog.png"];
[av setValue:imageView forKey:#"accessoryView"];
[av show];
}
#Popeye is correct what he said : UIAlertView is meant to be used as-is and you shouldn't be messing with the view hierarchy this will get your app rejected from the Apple App review process. Please read Apple documentation regarding UIAlertViews. So you should NOT be using setValue: forKey:#"accessoryView" and/or addSubview:. Specific section below
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.
Solutions
1) Use 3 party such as CNPPopupController and many other available check this link
OR
2) create of your own.
I added UIAlertController in my app by creating a category on UIViewController with the following method:
- (void)showAlertViewWithTitle:(NSString *)title
message:(NSString *)message
actions:(NSArray *)alertActions
{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title ? : #"" message:message preferredStyle:UIAlertControllerStyleAlert];
if (alertActions.count) {
for (UIAlertAction *action in alertActions) {
[alertController addAction:action];
}
} else {
UIAlertAction *action = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:action];
}
[self presentViewController:alertController animated:YES completion:nil];
}
At first, everything looks great but when I analyze leaks with Instruments, each time I call this method, some leaks appear:
Here is how the call of showAlertViewWithTitle:message:actions: is done
[self showAlertViewWithTitle:nil message:#"Test message" actions:nil];
Any idea why I get all these leaks?
-- EDIT --
I tried the following in a sample project:
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"title" message:#"message"
delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
and I get the same leaks. I'm really not sure what's going on...
This is an iOS bug.
This is also a duplicate of SO question iOS 8 Only Memory Leak with UIAlertController or UIActionSheet posted 1 day earlier.
See Apple Bug Reporter issue 21005708, Memory leak in UIAlertController under ARC.
The leak seems to be fixed with iOS 8.2 and Xcode 6.2