after calling an func for init the UIAlertController remains nil - objective-c

I have 2 alerts I want to present in different cases, I wrote a general function to init the alerts in the beginning and change the messages later, but when I am trying to present the alert I get a crash. When I inspect the notesAlert in runtime it is still nil.
Can someone explain what I did wrong?
#interface viewController (){
UIAlertController *tableAlert;
UIAlertController *notesAlert;
}
#end
#implementation viewController
- (void)viewDidLoad {
[super viewDidLoad];
[self initAlert:tableAlert];
[self initAlert:notesAlert];
}
// func to init the alerts
-(void)initAlert:(UIAlertController*)alert{
alert = [UIAlertController alertControllerWithTitle: #"" message: #"" preferredStyle:UIAlertControllerStyleActionSheet];
[alert setModalPresentationStyle:UIModalPresentationPopover];
[alert.popoverPresentationController setSourceView:self.view];
UIPopoverPresentationController *popover = [alert popoverPresentationController];
CGRect popoverFrame = CGRectMake(0,0, self.view.frame.size.width/2, self.view.frame.size.width/2);
popover.sourceRect = popoverFrame;
UIAlertAction *dismiss = [UIAlertAction actionWithTitle:#"Ok" style:UIAlertActionStyleDefault handler:nil];
[alert addAction:dismiss];
}
- (IBAction)showNotes:(id)sender {
// here the notesAlert is still nil
[notesAlert setTitle:#"oops"];
[notesAlert setMessage:#"you pressed the wrong one"];
[self presentViewController:notesAlert animated:YES completion:nil];
}
#end

[self initAlert: notesAlert]; doesn't create notesAlert. Instead, you could use notesAlert = [self initAlert];
Maybe something like this:
#interface ViewController () {
UIAlertController *tableAlert;
UIAlertController *notesAlert;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tableAlert = [self initAlert];
self.notesAlert = [self initAlert];
}
// func to init the alerts
- (UIAlertController *) initAlert {
UIAlertController *alert = [UIAlertController alertControllerWithTitle: #"" message: #"" preferredStyle: UIAlertControllerStyleActionSheet];
[alert setModalPresentationStyle:UIModalPresentationPopover];
[alert.popoverPresentationController setSourceView: self.view];
UIPopoverPresentationController *popover = [alert popoverPresentationController];
CGRect popoverFrame = CGRectMake(0,0, self.view.frame.size.width/2, self.view.frame.size.width/2);
popover.sourceRect = popoverFrame;
UIAlertAction *dismiss = [UIAlertAction actionWithTitle: #"Ok" style: UIAlertActionStyleDefault handler:nil];
[alert addAction: dismiss];
return alert;
}

Related

What's a simple way to get a text input popup dialog box with Actionsheet picker on an iPhone

want to get input from pickerView in textField when alert show Objective C
NOTE: Opening actionsheet from alertview first dismiss your alertview then open actionsheet.My code may help you regarding opening actionsheet from alertview
#import "ViewController.h"
#interface ViewController ()<UITextFieldDelegate,UIActionSheetDelegate>
{
NSString *alertSelectValue;
UITextField * alertTextField;
}
#end
#implementation ViewController
- (void)viewDidLoad {
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:#"Hello!" message:#"Please enter your name:" delegate:self cancelButtonTitle:#"Continue" otherButtonTitles:nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
UITextField * alertTextField = [alert textFieldAtIndex:0];
alertTextField.tag=101;
alertTextField.delegate=self;
alertTextField.keyboardType = UIKeyboardTypeNumberPad; alertTextField.placeholder = #"Enter your name";
[alert show];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
if (textField.tag==101)
{
[textField setUserInteractionEnabled:YES];
[textField resignFirstResponder];
NSString*String = [NSString stringWithFormat:#"%#",textField.text];
[self openSheet:String];
}
}
-(void)openSheet:(NSString*)text
{
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:#"Select" delegate:self cancelButtonTitle:#"OK" destructiveButtonTitle:nil otherButtonTitles:text,#"Test" ,nil];
actionSheet.actionSheetStyle = UIActionSheetStyleDefault;
UIViewController *topvc=[self topMostController];
[actionSheet showInView:topvc.view];
}
//-------- Get top Most view to -----
- (UIViewController*) topMostController
{
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topController.presentedViewController) {
topController = topController.presentedViewController;
}
return topController;
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSLog(#"Index = %d - Title = %#", buttonIndex, [actionSheet buttonTitleAtIndex:buttonIndex]);
if(buttonIndex == 0)
{
alertTextField.text= [actionSheet buttonTitleAtIndex:buttonIndex];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end

UItextField - iOS multiple line textfield on AlertView

Here is my code
I am adding uitextfield to alertview , what I need is to get the data from the array to uitextfield with multiple lines and should be editable.
NSString *selected = [lineItemsArray objectAtIndex:indexPath.row];
UIAlertController *controller = [UIAlertController alertControllerWithTitle:#"Notice" message:#"Selected" preferredStyle:UIAlertControllerStyleAlert];
[controller addTextFieldWithConfigurationHandler:^(UITextField *linetextField)
{
linetextField.text=selected;
}];
UIAlertAction *alertAction = [UIAlertAction actionWithTitle:#"Okay"
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction *action) {
[self.navigationController popViewControllerAnimated:YES];
NSLog(#"Dismiss button tapped!");
}];
[controller addAction:alertAction];
[self presentViewController:controller animated:YES completion:nil];
PackageLineItemViewController *pLineVC = [[PackageLineItemViewController alloc]init];
pLineVC.view.backgroundColor = [UIColor whiteColor];
[self.navigationController pushViewController:pLineVC animated:YES];
[self.view endEditing:YES];
I tried the solution for your question.If you use alertViewController with textField you can't set multiple line.For label you can set multiple line but for textfield you can't set.
#import "ViewController.h"
#interface ViewController ()<UITextFieldDelegate>
{
NSArray *arr;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
arr = [NSArray arrayWithObjects:#"iOS",#"Android",#"Windows",nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)actionShowClickTextField:(id)sender
{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil
message:#"Enter your text"
preferredStyle:UIAlertControllerStyleAlert];
[alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.delegate = self;
textField.text = #"";
for(int i=0;i<[arr count];i++)
{
textField.text = [textField.text stringByAppendingString:[NSString stringWithFormat:#"%#,\n",[arr objectAtIndex:i]]];
}
NSLog(#"The textField text is - %#",textField.text);
}];
[self presentViewController:alertController animated:YES completion:nil];
UIAlertAction *actionAlert = [UIAlertAction actionWithTitle:#"Save"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
// access text from text field
NSString *text = ((UITextField *)[alertController.textFields objectAtIndex:0]).text;
NSLog(#"The text is- %#",text);
}];
actionAlert.enabled = YES;
[alertController addAction:actionAlert];
}
#end
The printed output results are
The textField text is - iOS, Android, Windows
UITextFIeld is specific to one line. you cannot have multi-line textfeild. IF you need multi line , you should go for UITextView. Again you cannot add UITextView to the alert controller. You need to build a custom alert view.

How to properly use a UIAlertAction handler in Objective-C

Simply put, I would like to call a method or reference a variable from my class in a UIAlertAction handler.
Do I need to pass in a block to this handler or is there some other means to achieve this?
#interface OSAlertAllView ()
#property (nonatomic, strong) NSString *aString;
#end
#implementation OSAlertAllView
+ (void)alertWithTitle:(NSString *)title message:(NSString *)msg cancelTitle:(NSString *)cancel inView:(UIViewController *)view
{
__weak __typeof(self) weakSelf = self;
UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:msg
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:cancel style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
// I'd like to reference a variable or method here
weakSelf.aString = #"Apples"; // Not sure if this would be necessary
self.aString = #"Apples"; // Member reference type 'struct objc_class *' is a pointer Error
[self someMethod]; // No known class method Error
}];
[alert addAction:defaultAction];
[view presentViewController:alert animated:YES completion:nil];
}
- (void)someMethod {
}
The + at the start of your alertWithTitle... method means it is a class method. When you call it, self will be the class OSAlertAllView, not an instance of type OSAlertAllView.
There are two ways you could change it to make it work.
Change the + at the start of the method to a - making it an instance method. Then you would call it on an instance instead of the class.
// Old Class Method Way
[OSAlertAllView alertWithTitle:#"Title" message:#"Message" cancelTitle:#"Cancel" inView:viewController];
// New Instance Methods Way
OSAlertAllView *alert = [OSAlertAllView new];
[alert alertWithTitle:#"Title" message:#"Message" cancelTitle:#"Cancel" inView:viewController];
The other way would be to create an instance to OSAlertAllView inside of you alertWithTitle... and replace the uses of self with that object.
+ (void)alertWithTitle:(NSString *)title message:(NSString *)msg cancelTitle:(NSString *)cancel inView:(UIViewController *)view
{
OSAlertAllView *alertAllView = [OSAlertAllView new];
UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:msg
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:cancel style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
alertAllView.aString = #"Apples";
[alertAllView someMethod];
}];
[alert addAction:defaultAction];
[view presentViewController:alert animated:YES completion:nil];
}

No known class method for selector presentViewController in UIAlertController

I know it is a very simple question and i am working on it since 3 hour but didn't able to make it working. I am trying to implement UIAlertController to show error message using Apple documentation, but i am getting error on this line that no known class method for selector presentViewController [self presentViewController:alert animated:YES completion:nil]; I searched and got many solutions but none is working here. AlertMessageViewController is my custom class, which is inherited from UIViewController.
AlertMessageViewController.h
#import <UIKit/UIKit.h>
#interface AlertMessageViewController : UIViewController
+(instancetype)showAlert: (NSString *) title withMessage: (NSString*) message preferredStyle:(UIAlertControllerStyle)preferredStyle;
#end
AlertMessageViewController.m
#import "AlertMessageViewController.h"
#import <UIKit/UIKit.h>
#interface AlertMessageViewController ()
#end
#implementation AlertMessageViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
+(instancetype)showAlert: (NSString *) title withMessage: (NSString*) message preferredStyle:(UIAlertControllerStyle)preferredStyle
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"title" message:#"alertMessage" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *ok =[UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){NSLog(#"ok action");}];
[alert addAction:ok];
[self presentViewController:alert animated:YES completion:nil];
}
#end
Why is your return type for showAlert: method instancetype? And you didn't return anything, it should be void.
EDIT: Also, your method shouldn't be Class method
this should work:
-(void)showAlert: (NSString *) title withMessage: (NSString*) message preferredStyle:(UIAlertControllerStyle)preferredStyle
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"title" message:#"alertMessage" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *ok =[UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){NSLog(#"ok action");}];
[alert addAction:ok];
[self presentViewController:alert animated:YES completion:nil];
}
UPDATE:
Okay try this:
+(UIAlertController*)alertWithTitle: (NSString *) title withMessage: (NSString*) message preferredStyle:(UIAlertControllerStyle)preferredStyle
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle: preferredStyle];
UIAlertAction *ok =[UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){NSLog(#"ok action");}];
[alert addAction:ok];
return alert;
}
}
Then when you want to show it, call it like this:
[self presentViewController:[AlertMessageViewController alertWithTitle:#"Title" withMessage:#"Message" preferredStyle:UIAlertControllerStyleAlert] animated:YES completion:NULL];

How to use a UIAlert to open a NIB or UIView

Here is my code so far I can get a URL to work but I want to load a nib from this Alert tab
- (IBAction)aboutAction { // The action called when the about button is clicked.
UIAlertView * aboutView = [[UIAlertView alloc] initWithTitle:#"Alert:" // Create a new UIAlertView named aboutScreen, and allocate it. Set the title to "About"
message:#"MESSAGE GOES HERE"
delegate:self
cancelButtonTitle:#"Got It Thanks!"
otherButtonTitles:#"Donate Now", nil];
[aboutView show]; // Show the UIAlertView on the screen.
[aboutView release]; // Release the UIAlertView from the memory.
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if(buttonIndex == 1) { //Not sure what to do here.
}
}
-(void) alertView:(UIAlertView *) alertview clickedButtonAtIndex:(NSInteger)buttonIndex {
switch (buttonIndex) {
case 1: {
Accidenthelpercall *help = [[Accidenthelpercall alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:help animated:NO];
}
case 2: {
Accidentdamagecar *damagecar = [[Accidentdamagecar alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:damagecar animated:NO];
}
}
-(void) alertView:(UIAlertView *) alertview clickedButtonAtIndex:(NSInteger)buttonIndex {
switch (buttonIndex) {
case 1: {
Accidenthelpercall *help = [[Accidenthelpercall alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:help animated:NO];
[help release];
}
case 2: {
Accidentdamagecar *damagecar = [[Accidentdamagecar alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:damagecar animated:NO];
[damagecar release];
}
}