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];
}
Related
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!
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];
I have created 2 text Fields (Username and Phone number) when I executed my code, only text1(username) is getting executed. i got alert view, in the same way, i tried to give alert view that is text2(phone number) it must allow numeric numbers,
but in my code unable execute second if statement-text2 (phone number)
.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UITextFieldDelegate>
{
__weak IBOutlet UITextField *text1;
__weak IBOutlet UITextField *text2;
IBOutlet UIAlertView *alert;
}
#property (weak, nonatomic) IBOutlet UITextField *text1;
#property (weak, nonatomic) IBOutlet UITextField *text2;
#property (strong, nonatomic) IBOutlet UIAlertView *alert;
#end
.M
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
{
UIAlertView *prompt;
}
#synthesize text1;
#synthesize alert;
#synthesize text2;
- (void)viewDidLoad
{
[super viewDidLoad];
text1.delegate = self;
text2.delegate=self;
}
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if(textField==text1)
{
NSCharacterSet *myCharSet = [NSCharacterSet characterSetWithCharactersInString:#"0123456789"];
for (int i = 0; i < [string length]; i++)
{
unichar c = [string characterAtIndex:i];
if (![myCharSet characterIsMember:c])
{
alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"only number allowed" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
return NO;
}
}
return YES;
}
if (textField==text2)
{
NSLog(#"GOOD day");
NSCharacterSet *myCharSet1 = [NSCharacterSet characterSetWithCharactersInString:#"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"];
for (int i = 0; i < [string length]; i++)
{
unichar c1 = [string characterAtIndex:i];
if (![myCharSet1 characterIsMember:c1])
{
alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"number not allowed" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
return NO;
}
}
}
return YES;
}
#end
You have not set delegate for second textfield. Set delegate of text2 same as text1 as below
- (void)viewDidLoad
{
[super viewDidLoad];
text1.delegate = self;
text2.delegate = self;
}
And for compare UITextField you should use isEqual: instead of = operator. Hence is should be like
if ([textField isEqual:text1]){
.......
Your code here
.......
}
if ([textField isEqual:text2]){
.......
Your code here
.......
}
Change your keyboard type as UIKeyboardTypePhonePad for your phoneTextFeild
phoneTextFeild.keyboardType=UIKeyboardTypePhonePad;
i am trying to replace an object at in an array by replacing it with the text returned from an alert view.
so far i have:
int selected = indexPath.row;
and for my alertview delegate method.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (alertView.tag == 1) {
[myMutableArray replaceObjectAtIndex:selected withObject:[[alertView textFieldAtIndex:0] text]];
[_tableView reloadData];
}
}
i keep getting an error of
Incompatible integer to pointer conversion assigning to 'NSInteger *' (aka 'long *') from 'NSInteger' (aka 'long')
The error you see comes from the fact that you put a * somewhere before the NSInteger variable.
Without knowing what the rest of your code looks like, you could try this in your ViewController.m file. It sets the text of a label and replaces an object in a mutable array with the text from the alert view when the "OK" button is pressed.
#import "ViewController.h"
#interface ViewController () <UIAlertViewDelegate>
#property (strong,nonatomic) NSMutableArray *mutArray;
#property (weak,nonatomic) IBOutlet UILabel *label;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *array = #[#"item1",#"item2",#"item3"];
self.mutArray = [[NSMutableArray alloc] init];
self.mutArray = [array mutableCopy];
}
- (IBAction)showAlert:(id)sender {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"My Alert Example"
message:#"message here"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"OK",nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
int selected = 1;
if (buttonIndex != alertView.cancelButtonIndex) {
NSLog(#"ok button");
UITextField *textField = [alertView textFieldAtIndex:0];
self.label.text = textField.text;
[self.mutArray replaceObjectAtIndex:selected withObject:textField.text];
NSLog(#"mutArray is %#",self.mutArray);
} else {
NSLog(#"cancel button");
}
}
#end
Since it looks like you're using a UITableView, in your case you would have int selected = indexPath.row instead of int selected = 1.
I am making a calculator using Xcode iOS SDK 6.1. However, I have faced a problem because my calculator cannot add the two numbers together. It seems that the calculator always give me the first number as an answer. Is there a way to solve the problem?
Here's the code:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize FirstNumber,SecondNumber;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.FirstNumber.delegate = self;
self.SecondNumber.delegate = self;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)dealloc
{
[FirstNumber release];
[SecondNumber release];
[super dealloc];
}
- (IBAction)Calculate:(id)sender
{
NSString *finalNumberString;
int firstNumberInt, secondNumberInt, finalNumberInt;
firstNumberInt = [FirstNumber.text integerValue];
secondNumberInt = [SecondNumber.text integerValue];
finalNumberInt = firstNumberInt + secondNumberInt;
UIAlertView *alerting = [[UIAlertView alloc]initWithTitle:#"Answer" message:[NSString stringWithFormat:#"The answer is %d",finalNumberInt] delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles: nil];
[alerting show];
_FinalNumber.text = [[NSString alloc] initWithFormat:#"%i",finalNumberInt];
}
- (BOOL)textFieldShouldReturn:(UITextField*)textField
{
[FirstNumber resignFirstResponder];
[SecondNumber resignFirstResponder];
return NO;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if ([touch view] == self.view)
{
[FirstNumber resignFirstResponder];
[SecondNumber resignFirstResponder];
}
}
#end
It looks like you're showing the wrong value in the alert.
[NSString stringWithFormat:#"The answer is %d",secondNumberInt]
This should probably be
[NSString stringWithFormat:#"The answer is %d", finalNumberInt]
instead.
UIAlertView *alerting = [[UIAlertView alloc]initWithTitle:#"Answer" message:[NSString stringWithFormat:#"The answer is %d",secondNumberInt] delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles: nil];
secondNumberInt looks like it should be finalNumberInt
Incorrect values used as make the Alert message,
UIAlertView *alerting = [[UIAlertView alloc]initWithTitle:#"Answer" message:[NSString stringWithFormat:#"The answer is %d",secondNumberInt] delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles: nil];
[alerting show];
Change that part like this,
UIAlertView *alerting = [[UIAlertView alloc]initWithTitle:#"Answer" message:[NSString stringWithFormat:#"The answer is %d",finalNumberInt] delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles: nil];
[alerting show];
Try to put an NSLog between the two integer casts, and check if strings are read fine or if one of them is zero. If one of them is zero, probably you haven't connected the outlet to the UITextField in interface builder, or maybe you are just typing some weird string in the textfield: since you are casting to integer, you obiouvsly shouldn't put decimal digits.
firstNumberInt = [FirstNumber.text integerValue];
secondNumberInt = [SecondNumber.text integerValue];
NSLog(#"FirstNumber string %# integer %d", FirstNumber.text, firstNumberInt);
NSLog(#"SecondNumber string %# integer %d", SecondNumber.text, secondNumberInt);
finalNumberInt = firstNumberInt + secondNumberInt;