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.
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 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
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];
I am creating a drawing application where the user can draw using their finger strokes. I am trying to make a button that asks the user if they would like to clear the canvas. This alert has two buttons "Yes" and "No". I have the alert view appearing correctly but I have spent all day trying to figure out how to hook the buttons up to actions. I have so far had no success even after reading and watching from many instructional sources. From everything that I have read I can't understand why it would not be working. I have included UIAlertViewDelegate in my .h file also.
Here is my alert view:
- (IBAction)clearButton:(id)sender {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Clear Canvas"
message:#"Are you sure?"
delegate:nil
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes", nil];
[alert show];
}
Here is my clear canvas method:
- (void)clearCanvas:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 1)
drawImage.image = nil;
}
Any help or pointers would be greatly appreciated! I'm self taught and still very much a beginner!
Thanks!
- (IBAction)clearButton:(id)sender {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Clear Canvas"
message:#"Are you sure?"
delegate:self
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes", nil];
[alert show];
}
Notice the difference in the delegate parameter. You must conform to the delegate you have declared in the .h
Secondly, use the delegate method -alertView:clickedButtonAtIndex
I have this code
- (IBAction)save:(id)sender {
self.imageView.image = [UIImage imageNamed:#"loading.gif"];
[self.view setUserInteractionEnabled:NO];
MBProgressHUD *hudSave = [MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];
hudSave.labelText = #"Saving...";
NSLog(#"save");
UIAlertView *deco;
if (!isVideo) {
UIImageWriteToSavedPhotosAlbum (imageView.image, nil, nil , nil);
deco = [[UIAlertView alloc]initWithTitle:#"Save" message:#"Your photo has been saved." delegate: nil cancelButtonTitle:#"oK" otherButtonTitles:nil];
}else{
//UIAlertView *explain;
//explain = [[UIAlertView alloc]initWithTitle:#"Wait during processing" message:#"Your video is being filtered, this process may be long, depending of both video and device. Please do not close this app until task is finished." delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
UIAlertView *explain;
explain = [[UIAlertView alloc]initWithTitle:#"Wait during processing" message:#"Your video is being filtered, this process may be long, depending of both video and device. Please do not close this app until task is finished." delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[explain show];
[self InitialisationRefiltrage:urlVideo];
//[self InitialisationRefiltrage:urlVideo];
deco = [[UIAlertView alloc]initWithTitle:#"Save" message:#"Your video has been saved." delegate: nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
}
[MBProgressHUD hideHUDForView:self.navigationController.view animated:YES];
[deco show];
[self.view setUserInteractionEnabled:YES];
}
The problem part is if my file is a video, it goes directly too "initialisationRefiltrage" (who is working fine) but without displaying the MBProgressHUD and the alert view explain, and after my video traitement, it display everything (explain, deco, and the MBProgressHUD) at the same time.
I try something with dispatch, thread, etc... But i think a don't do it correctly, so can you please give me a clue too how to do that.
Have a nice day.
Put the code [self InitialisationRefiltrage:urlVideo] in the delegate method of your UIAlertView so that it is executed only when the alert has been displayed and user has tapped on a button of the alert.
You may also use instead some third-party UIAlertView subclasses that uses completion blocks to make your code only execute when the alert is dismissed. See my class that does this for example.
Besides, you should respect coding conventions and use a method name beginning with a lowercase letter to make your code more readable.
The UI is updated in the "run loop".
The calls you're making tell iOS to display some views (alert, MUD...) and it'll do that on the next run through the loop.
What you need to do is wait for the user to respond to the alert before continuing. You do this by setting yourself as the UIAlert's delegate, then responding to the event:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
...
}
There are also libraries available that allow you to pass a block to the alert view, thus simplifying the whole thing. (https://github.com/jivadevoe/UIAlertView-Blocks, for example)
P.S. I see that you're new to Stack Overflow - please tick my answer if you're happy that it has responded to your question...