insert UITextField (from a UIAlertController) into an NSMutableArray - objective-c

Hello I am tying to insert user input attained from an alert txtfield into a mutable array.
So, I have a tableView with a button to add a additional row. When the button is pressed the user can enter a message.
I would like to have that message be inserted into my array.
I was going to use the method clickedButtonAtIndex but Xcode states that that method is now deprecated.
Is there any other way to go about doing this??
here is the code for my array:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.exampleMessages = [[NSMutableArray alloc]initWithObjects:#"Example Message..", #"Example Message..",#"Example Message..",#"Example Message..",#"Example Message..", #"Example Message..",#"Example Message..",#"Example Message..", nil];}
here is my function that is executed once the add row button is pressed:
- (void)insertNewObject
//function that is executed after a new object is inserted
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#""
message:nil
preferredStyle:UIAlertControllerStyleAlert];
//create a UIAlert named alert
[alert addTextFieldWithConfigurationHandler:^(UITextField *messageTextField) {
messageTextField.placeholder = NSLocalizedString(#"message content", #"Message");
}];
//add a UITextField to the UIAlert
UIAlertAction *messageAction = [UIAlertAction
actionWithTitle:NSLocalizedString(#"Add", #"Message action")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
UITextField *userMessage = alert.textFields.firstObject;
NSLog(#"%#", userMessage);
//capture the value of the UITextField
}];
//add a button called "add"
UIAlertAction *cancelAction = [UIAlertAction
actionWithTitle:NSLocalizedString(#"Cancel", #"Cancel action")
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action) {}];
//add a button called "cancel"
[alert addAction:messageAction];
//add the add button to the alert
[alert addAction:cancelAction];
//add the cancel button to the alert
[self presentViewController:alert animated:YES completion:nil];
//present the alert to the UI
}
In the code right here I am capturing the value and storing it in a variable but now how do I put it in my array?
UITextField *userMessage = alert.textFields.firstObject;
NSLog(#"%#", userMessage);
//capture the value of the UITextField

Replace comment
//capture the value of the UITextField
with the following line:
[self.exampleMessages addObject:userMessage.text ?: #""];
Looks like after that you will need to update table view, via [self.tableView reloadData] or similar call.

Related

Show keyboard when Textfield inside Alert in WkWebView is tapped

There is a game that i load in the WKWebView and this Alert and textField appear after the game is finished. I want to display keyboard when user taps on the textField. But the problem is there is no code to display this alert and textfield, otherwise i would have managed the textField to becomeFirstResponder().
Desperately need some help. I would really appreciate it.
Okay so i have found the solution. I had a textField in custom Alert/Popup in WkwebView and i wanted the textField to becomeFirstResponder() so i could take user input.
// So i Implemented WKUIDelegate..
#import <WebKit/WebKit.h>
#interface MyController : UIViewController<WKUIDelegate>
Assigned the Delegate..
- (void)viewDidLoad {
[super viewDidLoad];
_webkitView.UIDelegate = self;
}
//implemented delegate function.
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *result))completionHandler
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"BlockChaid Id, Email or Username"
message:prompt
preferredStyle:UIAlertControllerStyleAlert];
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.placeholder = prompt;
textField.secureTextEntry = NO;
textField.text = defaultText;
}];
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedString(#"Cancel", nil) style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
completionHandler(nil);
}]];
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedString(#"OK", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
completionHandler([alert.textFields.firstObject text]);
}]];
[self presentViewController:alert animated:YES completion:nil];
}
After successful build, this was the output.
I tapped the textField, and javaScript Alert appeared.
This right here is what i wanted to achieve.
Maybe i was not good enough to explain my question, but this is what i was asking for. Thank you :)

UIAlertController disappearing since iOS 13

I have the following function that pops up a UIAlert which allows the user to update their Haptic Feedback setting:
- (void)requestHapticSetting{
UIWindow *alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
alertWindow.rootViewController = [[UIViewController alloc] init];
alertWindow.windowLevel = UIWindowLevelAlert + 1;
[alertWindow makeKeyAndVisible];
if(isHapticOn){
hapticMessage = #"Haptic feedback is currently\nturned ON.\nPlease update preference.";
}
else {
hapticMessage = #"Haptic feedback is currently\nturned OFF.\nPlease update preference.";
}
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#"Haptic Setting"
message:hapticMessage
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* onAction = [UIAlertAction actionWithTitle:#"TURN ON" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[self saveHapticSettingOn];
}];
UIAlertAction* offAction = [UIAlertAction actionWithTitle:#"TURN OFF" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[self saveHapticSettingOff];
}];
[alert addAction:offAction];
[alert addAction:onAction];
[alertWindow.rootViewController presentViewController:alert animated:YES completion:nil];
}
I have used this for a couple of years and it works great.
However, since updating to iOS 13 and updating to the latest Xcode, my alert pops up for less than a second before closing.
What has changed that could be making this happen? Thanks in advance.
What seems to have changed is that on iOS 12 and previous versions your app would hold a strong reference to the window just by calling [alertWindow makeKeyAndVisible];, in iOS 13 it doesn't anymore.
What's happening is that the only strong reference to your alertWindow is in your requestHapticSetting func, and as soon as this func returns, the window is destroyed, thus removing your alert from the view.
This might be fixed just by adopting iOS 13 scenes, but I haven't tested that. What I can suggest, which won't properly work if you are using scenes, is holding your alert window in a strong variable somewhere in your code, and then using it to present the alert. I'd suggest doing so in a singleton or AppDelegate itself.
//AppDelegate.h
...
#property (strong) UIWindow *alertWindow;
....
//AppDelegate.m
...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...
self.alertWindow = [[UIWindow alloc] init];
self.alertWindow.rootViewController = [[UIViewController alloc] init];
self.alertWindow.windowLevel = UIWindowLevelAlert + 1;
...
}
...
//Your class that's presenting the alert
#import "AppDelegate.h"
...
- (void)requestHapticSetting{
AppDelegate *appDelegate = (AppDelegate *)UIApplication.sharedApplication;
[appDelegate.alertWindow makeKeyAndVisible];
if(isHapticOn){
hapticMessage = #"Haptic feedback is currently\nturned ON.\nPlease update preference.";
} else {
hapticMessage = #"Haptic feedback is currently\nturned OFF.\nPlease update preference.";
}
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#"Haptic Setting"
message:hapticMessage
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* onAction = [UIAlertAction actionWithTitle:#"TURN ON" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[self saveHapticSettingOn];
[appDelegate.alertWindow setHidden:YES];
}];
UIAlertAction* offAction = [UIAlertAction actionWithTitle:#"TURN OFF" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[self saveHapticSettingOff];
[appDelegate.alertWindow setHidden:YES];
}];
[alert addAction:offAction];
[alert addAction:onAction];
[appDelegate.alertWindow.rootViewController presentViewController:alert animated:YES completion:nil];
}
For Swift code, check this answer.
I have created a helper class which support new UIWindowScene and iOS 13.X and swift 5.X. You guys can try
https://github.com/emraz/ERAlertController

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.

iPad crashes when showing photos or taking photo--nil source view

The follow code crashes when run on an iPad with the error message:
(<UIPopoverPresentationController: 0x1377a19e0>) should have a non-nil
sourceView or barButtonItem set before the presentation occurs.'
However, in my code I have the following, and I checked with breakpoints and console prinouts to ensure sourceview and barbutton are not nil. What do I need to do to avoid this? The error only appears on an iPad. Here is the method that causes trouble:
- (void)showChooseImageOptions {
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *chooseAction = [UIAlertAction actionWithTitle:#"Choose From Photos" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
[self showLibrary];
}];
UIAlertAction *takeAction = [UIAlertAction actionWithTitle:#"Take Photo" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
[self showCamera];
}];
self.directionsTextView.text=#"";
[alertController addAction:chooseAction];
[alertController addAction:takeAction];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
if (self.imageView.image) {
self.directionsTextView.text=#"Tap the circle to change the image";
} else{
self.directionsTextView.text=#"Tap the blue circle to choose or take an image";
}
}];
[alertController addAction:cancelAction];
alertController.view.tintColor=[ColorSuperclass returnApplicationMainColor];
alertController.popoverPresentationController.barButtonItem = self.navigationItem.rightBarButtonItem;
if ( [alertController respondsToSelector:#selector(popoverPresentationController)] ) {
// at least iOS8
alertController.popoverPresentationController.sourceView = self.view;
}
[self presentViewController:alertController animated:YES completion:nil];
}
And the method showCamera and showLibrary are nothing but:
-(void)showCamera {
if (TARGET_IPHONE_SIMULATOR) {
//do nothing, the simulator cannot handle pressing the take photos...
} else{
[self showImagePickerForSourceType:UIImagePickerControllerSourceTypeCamera];
}
}
- (void)showLibrary {
[self showImagePickerForSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
}
and the show source type method:
- (void)showImagePickerForSourceType:(UIImagePickerControllerSourceType)sourceType {
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.modalPresentationStyle = UIModalPresentationPopover; //this line is very important, because otherwise, the tab bar could go out of scope (a consequence of using modal segues and tab controllers!)
imagePickerController.sourceType = sourceType;
imagePickerController.delegate = self;
imagePickerController.allowsEditing = YES;
[self presentViewController:imagePickerController animated:YES completion:nil];
}

UIAlertController handler becomes nil

I have an UIAlertController in my app, so i want show alert everytime menuButton pressed. I need to recreate _menuAlert for specific idea (It need to check object for another action,that are not described). So if i keep _shareAction, but recreate UIAlertController, somehow, it's handler becomes nil.
I feel missing something big about blocks to understand why this happens. Please, help me understand.
There is code:
- (UIAlertController *)menuAlert
{
_menuAlert = [UIAlertController alertControllerWithTitle:nil
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
#weakify(self);
if (!_shareAction)
{
_shareAction = [UIAlertAction actionWithTitle:NSLocalizedString(#"SHARE_BTN_TEXT", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * _Nonnull action) {
#strongify(self);
[self.navigationController presentShareVCWithList:_list];
}];
}
if (!_cancelAction) {
_cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(#"ALERT_CANCEL", nil)
style:UIAlertActionStyleCancel
handler:nil];
}
[_menuAlert addAction:_shareAction];
[_menuAlert addAction:_cancelAction];
return _menuAlert;
}
How menuAlert called :
- (void)menuButtonPressed
{
[self presentViewController:self.menuAlert animated:YES completion:nil];
self.menuAlert.view.tintColor = COLOR_BACKGROUND_GREEN;
}