Probably a simple answer to this,
How can i pass the textField.text from an UIAlertView that has a textfield in it
to a -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
i tried to create a property NSString and make it equal to textField.text and tried to NSLog it and it came back NULL
Updated Answer
To retrieve the text of a text field in the UIAlertView you can use the textFieldAtIndex: method. You don't need to involve the text field delegate at all.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
UITextField *textField = [alertView textFieldAtIndex:0]; // adjust the index if you have more than one text field.
NSLog(#"Text: %#", textField.text);
}
Original Answer
You have a couple of options here.
Option 1
Store a reference to the text field as a property, it seems likely you are already doing this.
#property (nonatomic, weak) IBOutlet UITextField *textField;
This can then be accessed directly from the UIAlertView delegate method, assuming the delegate is the same object that has the reference to the text field:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
NSLog(#"Text: %#", self.textField.text);
}
Option 2
If for some reason you don't have a reference to your text field you can get it from the textFieldDidEndEditing: delegate method, firstly create a property to store the text:
#property (nonatomic, copy) NSString *textFieldText;
Then update that when the text field delegate method is called.
- (void)textFieldDidEndEditing:(UITextField *)textField {
self.textFieldText = textField.text;
}
Then you can access this property in the UIAlertView delegate method:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
NSLog(#"Text: %#", self.textFieldText);
}
This code is working for me:
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:#"" message:[NSString stringWithFormat:#"Do you want to call?"] delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"OK", nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
UITextField * alertTextField = [alert textFieldAtIndex:0];
alertTextField.keyboardType = UIKeyboardTypeNumberPad;
[alertTextField setTextAlignment:NSTextAlignmentCenter];
[alert show];
and delegates:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex==1) {
return;
}
UITextField *title1;// = [alertView textFieldAtIndex:0];
title1= [alertView textFieldAtIndex:0];
NSString *messageStr = title1.text;
if ([messageStr isEqualToString:#""]) {
return;
}}
you just declare NSString object in
#interface LoginDialogVC ()
{
NSString strText;
}
#end
#implementation LoginDialogVC
-(void)textFieldDidEndEditing:(UITextField *)textField {
strText = textField.text;
}
after that use strText whenever you want to use.
I am pretty new to objective c. I have looked through a ton of questions on stack overflow to try to find an answer but nothing has helped, so I appreciate any help anyone can offer.
I am trying to make an app that will have the picker view load from my array of 51 numbers. a random object will be generated from the array and if the user selects that object from the picker, an alert will show. I'm going to make a simple little guessing game, but for now I just have the picker that loads but is blank with no text. The alerts do work tho.
I have already assigned datasource and delegate to picker view on the view controller.
I need help figuring out why my picker view is not loading my array and what I can do to fix it. Thank you
here is my h file:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate>
#property (strong, nonatomic) IBOutlet UIPickerView *picker;
#end
here is m file:
#import "ViewController.h"
#interface ViewController ()
#property NSArray *numbers;
#property NSString * selection;
#property NSString *randomObject;
#property NSInteger rnd;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor darkGrayColor];
[_numbers arrayByAddingObjectsFromArray:_numbers];
}
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent: (NSInteger)component{
return _numbers.count;
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
_numbers = #[#0,#1,#2,#3,#4,#5,#6,#7,#8,#9,#10,#11,#12,#13,#14,#15,#16,#17,#18,#19,#20,#21,#22,#23,#24,#25,#26,#27,#28,#29,#30,#31,#32,#33,#34,#35,#36,#37,#38,#39,#40,#41,#42,#43,#44,#45,#46,#47,#48,#49,#50];
//create random object from array
_rnd = arc4random() % ([_numbers count]);
_selection = [NSString stringWithFormat:#"%ld",(long)row];
_randomObject = [_numbers objectAtIndex:self.rnd];
NSLog(#"%#",self.randomObject);
//strings for alerts
NSString *right = [[NSString alloc]initWithFormat:#"You Guessed Right! Congratulations you've earned 3 points!"];
NSString *oneOff = [[NSString alloc]initWithFormat:#"You were so close! Only 1 off! The number was %lu. Congratulations you've earned 2 points!",(unsigned long)self.rnd];
NSString *twoOff = [[NSString alloc]initWithFormat:#"You were so close! Only 2 off! The number was %lu. Congratulations you've earned 1 point!",(unsigned long)self.rnd];
NSString *threeOff = [[NSString alloc]initWithFormat:#"Nice try! You were 3 off. The number was %lu. You earned -1 point.",(unsigned long)self.rnd];
NSString *fourOff = [[NSString alloc]initWithFormat:#"Good try! You were 2 off. The number was %lu. You earned -2 points.",(unsigned long)self.rnd];
NSString *fiveOff = [[NSString alloc]initWithFormat:#"You were no where close! The number was %lu. You earned -3 points!",(unsigned long)self.rnd];
//alerts for guesses
UIAlertView *rightAlert = [[UIAlertView alloc]initWithTitle:#"Spot On!" message:right delegate:nil cancelButtonTitle:#"Sweet!" otherButtonTitles:nil, nil];
UIAlertView *oneOffAlert = [[UIAlertView alloc]initWithTitle:#"Only one off!" message:oneOff delegate:nil cancelButtonTitle:#"Ok!" otherButtonTitles:nil, nil];
UIAlertView *twoOffAlert = [[UIAlertView alloc]initWithTitle:#"Only Two Off!" message:twoOff delegate:nil cancelButtonTitle:#"Ok!" otherButtonTitles:nil, nil];
UIAlertView *threeOffAlert = [[UIAlertView alloc]initWithTitle:#"Three Off" message:threeOff delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
UIAlertView *fourOffAlert = [[UIAlertView alloc]initWithTitle:#"Four Off" message:fourOff delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
UIAlertView *fiveOffAlert = [[UIAlertView alloc]initWithTitle:#"No Where Close!" message:fiveOff delegate:nil cancelButtonTitle:#"Ok!" otherButtonTitles:nil, nil];
NSInteger a = [_selection integerValue];
//guessed right
if (_selection == _randomObject)
{
[rightAlert show];
}
//one off
if (a == (_rnd + 1) || (a == (_rnd - 1)))
{
[oneOffAlert show];
}
//two off
if (a == (_rnd + 2) || (a == (_rnd - 2)))
{
[twoOffAlert show];
}
//three off
if (a == (_rnd + 3) || (a == (_rnd - 3)))
{
[threeOffAlert show];
}
//four off
if (a == (_rnd + 4) || (a == (_rnd - 4)))
{
[fourOffAlert show];
}
//five or more off
if ((_rnd + 5) >= a || (_rnd - 5) <= a ||(_rnd - 5) >= a || (_rnd + 5) <= a)
{
[fiveOffAlert show];
}
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
return _numbers[row];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
The problem is that this line
_numbers = #[#0,#1,#2,#3,#4,#5,#6,#7,#8,#9,#10,#11,#12,#13,#14,#15,#16,#17,#18,#19,#20,#21,#22,#23,#24,#25,#26,#27,#28,#29,#30,#31,#32,#33,#34,#35,#36,#37,#38,#39,#40,#41,#42,#43,#44,#45,#46,#47,#48,#49,#50];
appears in the wrong place. It is in the pickerView:didSelectRow:inComponent: method which is only called after the user has made a selection. Therefore, your _numbers array will always be empty.
Move it to the viewDidLoad method, replacing the following statement which currently hasn't any effect at all:
[_numbers arrayByAddingObjectsFromArray:_numbers];
Also, you need to change this method:
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
return [_numbers[row] stringValue];
}
because _numbers[row] is an NSNumber, not an NSString.
I have found this solution to making the next buttons on the ui keyboard go to the next text field, however it is not working at all for me. Is there something I have to do in the storyboard as well? Also, how do I make the next button for the final textfield call the unwind segue? Thank you
//
// AddToDoItemViewController.m
// ToDoList
//
// Copyright (c) 2015 com.example. All rights reserved.
//
#import "AddToDoItemViewController.h"
#interface AddToDoItemViewController ()
#property (weak, nonatomic) IBOutlet UITextField *textField;
#property (weak, nonatomic) IBOutlet UIBarButtonItem *saveButton;
#property (weak, nonatomic) IBOutlet UITextField *totalTextField;
#property (weak, nonatomic) IBOutlet UITextField *tipTextField;
#property (weak, nonatomic) IBOutlet UIView *singleTableView;
#property (weak, nonatomic) IBOutlet UISwitch *ccSwitch;
#end
#implementation AddToDoItemViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
if (textField == self.textField) {
[self.totalTextField becomeFirstResponder];
}
else if (textField == self.totalTextField ) {
[self.tipTextField becomeFirstResponder];
}
else{
[textField resignFirstResponder];
}
return YES;
}
/*- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
if (theTextField == self.textField) {
[theTextField resignFirstResponder];
} else if (theTextField == self.totalTextField) {
[self.tipTextField becomeFirstResponder];
}
return YES;
}
*/
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
NSLog(#"sender = %#",sender);
if (sender != self.saveButton) return YES;
NSNumberFormatter *formatter1 = [[NSNumberFormatter alloc] init];
NSNumber *totalOrder = [formatter1 numberFromString:self.totalTextField.text];
NSNumber *tipOrder = [formatter1 numberFromString:self.tipTextField.text];
double tot = totalOrder.doubleValue;
double totalOrderWithTip = tipOrder.doubleValue;
if(self.textField.text.length <= 0)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Field not entered"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
return NO;
}
if(self.totalTextField.text.length <= 0)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Field not entered"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
return NO;
}
if(self.tipTextField.text.length <= 0)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Field not entered"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
return NO;
}
if(totalOrder == nil)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Invalid Order Total"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
return NO;
}
if(tipOrder == nil)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Invalid Amount Recieved"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
return NO;
}
if(totalOrderWithTip < tot)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"The amount recieved must be equal to or greater than the order total."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
return NO;
}
return YES;
}
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if (sender != self.saveButton) return;
if (self.textField.text.length > 0) {
NSNumberFormatter *formatter1 = [[NSNumberFormatter alloc] init];
// NSNumber *tipPercent = [[NSNumber alloc] initWithFloat:0.0];
NSNumber *totalOrder = [formatter1 numberFromString:self.totalTextField.text];
NSNumber *tipOrder = [formatter1 numberFromString:self.tipTextField.text];
NSNumber *actualTip = [[NSNumber alloc] initWithFloat:tipOrder.doubleValue - totalOrder.doubleValue];
double tot = totalOrder.doubleValue;
double tip1 = tipOrder.doubleValue - tot;
self.toDoItem = [[ToDoItem alloc] init];
self.toDoItem.location = self.textField.text;
NSNumber *percent1 = [[NSNumber alloc] initWithDouble:(tip1/tot)*100.0];
if(self.ccSwitch.isOn)
self.toDoItem.isCreditCard = YES;
else
self.toDoItem.isCreditCard = NO;
self.toDoItem.total = totalOrder;
self.toDoItem.tip = actualTip;
self.toDoItem.percentage = percent1;
self.toDoItem.completed = NO;
}
}
#end
In the Connections Inspector for the textField, drag from the "circle" under the section "Outlets" - "delegate", to the View Controller Icon. Or either you can set it in the viewDidLoad method. Some like:
self.textField.delegate = self;
The last textField is closing the keyboard because your are telling the keyboard to resign its first responder condition. Just replace that line for the one that you want to call:
[self shouldPerformSegueWithIdentifier:#"YOUR_IDENTIFIER" sender:your_sender];
And that's it!
This question already has an answer here:
Using text field to display an alert [closed]
(1 answer)
Closed 8 years ago.
I asked this question before but for some reason it says closed, but i never got the right answer,can anyone help me add a text field, where if the user types a number in text field once the number reaches the same number as the counter it displays an alert.
#import <UIKit/UIKit.h>
int NumberCount;
#interface ViewController : UIViewController
{
int counter;
IBOutlet UILabel *count;
}
-(IBAction)minus;
-(IBAction)plus;
-(IBAction)zero;
#end
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
-(IBAction)plus {
counter=counter + 1;
count.text = [NSString stringWithFormat:#"%i",counter];
}
-(IBAction)minus {
counter=counter - 1;
count.text = [NSString stringWithFormat:#"%i",counter];
}
-(IBAction)zero {
counter=0;
count.text = [NSString stringWithFormat:#"%i",counter];
}
- (void)viewDidLoad {
counter=0;
count.text = #"0";
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I tried adding this in but it didn't work
if (count.text == textField ) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Congrats"
message:#"You met that number"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
My ViewController.h :
__weak IBOutlet UITextField *textField;
You are comparing a string with an UITextField object.
You have to compare the count.text string with textField.text string.
Try this:
if ([count.text isEqualToString:textField.text]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Congrats"
message:#"You met that number"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
I have developed this class that is basically a UIAlertView with an input field that runs on blocks. So, whatever the user does on the alertView (click cancel, ok, or fill the text), returns to a block:
HEADER
typedef void (^onClickBlock)(NSInteger buttonIndex, NSString *textoInput);
#interface AlertViewBlocoComInput : NSObject
- (void)mostrarAlertViewBlocoComTitulo:(NSString *)titulo
mensagem:(NSString *)mensagem
tituloBotaoCancel:(NSString *)tituloCancel
outrosBotoesArray:(NSArray *)titulosOutrosBotoes
inputComPlaceHolder:(NSString *)textoPlaceholder
comBlocoExecucao:(onClickBlock)bloco;
#end
IMPLEMENTATION
#interface AlertComBloco : UIAlertView
#property (nonatomic, copy) onClickBlock runOnClickBlock;
#end
#implementation AlertComBloco
#end
#interface AlertViewBlocoComInput () <UIAlertViewDelegate>
#end
#implementation AlertViewBlocoComInput
- (void)mostrarAlertViewBlocoComTitulo:(NSString *)titulo
mensagem:(NSString *)mensagem
tituloBotaoCancel:(NSString *)tituloCancel
outrosBotoesArray:(NSArray *)titulosOutrosBotoes
inputComPlaceHolder:(NSString *)textoPlaceholder
comBlocoExecucao:(onClickBlock)bloco
{
AlertComBloco *alerta = [[AlertComBloco alloc] initWithTitle:titulo
message:mensagem
delegate:self
cancelButtonTitle:tituloCancel
otherButtonTitles:nil];
alerta.runOnClickBlock =bloco;
// adicionar os outros botões
for (NSString *umOutroBotao in titulosOutrosBotoes) {
[alerta addButtonWithTitle:umOutroBotao];
}
[alerta setAlertViewStyle:UIAlertViewStylePlainTextInput];
UITextField *input = [alerta textFieldAtIndex:0];
input.placeholder = textoPlaceholder;
[alerta show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
AlertComBloco *alerta = (AlertComBloco *)alertView;
onClickBlock bloco = alerta.runOnClickBlock;
UITextField *input = [alertView textFieldAtIndex:0];
if (bloco) {
bloco(buttonIndex, input.text);
}
}
#end
I run it, it shows the alertView with the message, placeholder, perfect. I click cancel or fill the text and press ok and the alertview:clickedButtonAtIndex: is never triggered. I am not seeing why.
thanks
You can directly subclass UIAlertView and add your own initializer. I have abstracted your classes to a single subclass of UIAlertView and it works fine. Please see my posts below,
typedef void (^onClickBlock)(NSInteger buttonIndex, NSString *textoInput);
#interface AlertComBloco : UIAlertView<UIAlertViewDelegate>
#property (nonatomic, copy) onClickBlock runOnClickBlock;
#end
#implementation AlertComBloco
- (id)initWithTitulo:(NSString *)titulo mensagem:(NSString*)mensagem tituloBotaoCancel:(NSString*)tituloCancel outrosBotoesArray:(NSArray *)titulosOutrosBotoes inputComPlaceHolder:(NSString *)textoPlaceholder
comBlocoExecucao:(onClickBlock)bloco{
if(self = [self initWithTitle:titulo message:mensagem delegate:self cancelButtonTitle:tituloCancel otherButtonTitles:nil, nil]){
_runOnClickBlock = bloco;
for (NSString *umOutroBotao in titulosOutrosBotoes) {
[self addButtonWithTitle:umOutroBotao];
}
[self setAlertViewStyle:UIAlertViewStylePlainTextInput];
UITextField *input = [self textFieldAtIndex:0];
input.placeholder = textoPlaceholder;
}
return self;
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
UITextField *input = [alertView textFieldAtIndex:0];
if (self.runOnClickBlock) {
self.runOnClickBlock(buttonIndex, input.text);
}
}
#end
Then, you could call it with the block in your view controller just like this,
- (void)showAlert:(id)sender{
AlertComBloco *alertCombo = [[AlertComBloco alloc] initWithTitulo:#"Hi" mensagem:#"Custom Alert" tituloBotaoCancel:#"Cancel" outrosBotoesArray:#[#"Other"] inputComPlaceHolder:#"Placeholder" comBlocoExecucao:^(NSInteger buttonIndex, NSString *textoInput) {
NSLog(#"Button at index %ld, with text %#", (long)buttonIndex, textoInput);
}];
[alertCombo show];
}
You haven't shown us how you're calling this but most likely your AlertViewBlocoComInput is a local variable that has fallen out of scope and is therefore deallocated before the user completes their input. You can demonstrate this by temporarily adding a dealloc method that will tell you when the object is deallocated.
- (void)dealloc {
NSLog(#"%s", __PRETTY_FUNCTION__);
}
In terms of fixing this, you could make your AlertViewBlocoComInput instance a class property, so it won't be released until you manually nil it. Or you can make AlertViewBlocoComInput maintain a strong reference to itself until clickedButtonAtIndex is called.
Or, easiest, leverage the fact that UIAlertView already retains itself, so you can retire AlertComBloco altogether, folding it into AlertViewBlocoComInput:
typedef void (^onClickBlock)(NSInteger buttonIndex, NSString *textoInput);
#interface AlertViewBlocoComInput : UIAlertView <UIAlertViewDelegate>
- (instancetype)initComTitulo:(NSString *)titulo
mensagem:(NSString *)mensagem
tituloBotaoCancel:(NSString *)tituloCancel
outrosBotoesArray:(NSArray *)titulosOutrosBotoes
inputComPlaceHolder:(NSString *)textoPlaceholder
comBlocoExecucao:(onClickBlock)bloco;
#property (nonatomic, copy) onClickBlock runOnClickBlock;
#end
#implementation AlertViewBlocoComInput
- (instancetype)initComTitulo:(NSString *)titulo
mensagem:(NSString *)mensagem
tituloBotaoCancel:(NSString *)tituloCancel
outrosBotoesArray:(NSArray *)titulosOutrosBotoes
inputComPlaceHolder:(NSString *)textoPlaceholder
comBlocoExecucao:(onClickBlock)bloco
{
self = [super initWithTitle:titulo message:mensagem delegate:self cancelButtonTitle:tituloCancel otherButtonTitles:nil];
if (self) {
self.runOnClickBlock =bloco;
// adicionar os outros botões
for (NSString *umOutroBotao in titulosOutrosBotoes) {
[self addButtonWithTitle:umOutroBotao];
}
[self setAlertViewStyle:UIAlertViewStylePlainTextInput];
UITextField *input = [self textFieldAtIndex:0];
input.placeholder = textoPlaceholder;
}
return self;
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (self.runOnClickBlock) {
UITextField *input = [alertView textFieldAtIndex:0];
self.runOnClickBlock(buttonIndex, input.text);
}
}
#end
And you'd call it like so:
AlertViewBlocoComInput *obj = [[AlertViewBlocoComInput alloc] initComTitulo:#"title" mensagem:#"message" tituloBotaoCancel:#"OK" outrosBotoesArray:nil inputComPlaceHolder:#"Placeholder" comBlocoExecucao:^(NSInteger buttonIndex, NSString *textoInput) {
// do whatever you want with `buttonIndex` and `textoInput` here
//
// NSLog(#"%ld %#", (long)buttonIndex, textoInput);
}];
[obj show];