UIButton title replacement with each press - objective-c

I would like to present to the user with each press of the button different letter from the ABC.
So when it first click on the application the user will see the letter A, then they will need to press the button and then they will see the letter B and so forth.
My challenge is how to replace the text of the title with each click on the button.
I wrote down some code, of two functions, if you will take a closer look you will see that -(void)displayABC:(id)sender is getting called each time so each time I getting the first member of the array, so first time the user see the letter A then it press on the button and she/he see the letter B which is the first member of the array, but each the same letter is been presented because each time, we loading the plist file and therefore we keep calling the first member of the array.
Any ideas how to solve it?
-(void)createLoginBioButton
{
authButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[authButton setBounds:CGRectMake(300,300, 150, 150)];
[authButton setCenter:CGPointMake(150, 240)];
[self.view addSubview:authButton];
[authButton setEnabled:true];
[authButton setTitle:#"A" forState:UIControlStateNormal];
[authButton setFont:[UIFont systemFontOfSize:70]];
[authButton addTarget:self
action:#selector(displayABC:)
forControlEvents:UIControlEventAllTouchEvents];
}
-(void)displayABC:(id)sender
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"ABC" ofType:#"plist"];
NSArray *ABCArray = [NSArray arrayWithContentsOfFile:path];
for (NSString *ABCValues in ABCArray){
[authButton setTitle:ABCValues forState:UIControlStateNormal];
}
}

Why not keep a reference to the current letter index as an instance variable and increment that with each touch?
Psuedo code
#property NSArray *abcs;
#property int currentIndex;
- (void)viewDidLoad {
[super viewDidLoad];
self.abcs = //load it from the plist
[self updateButtonText];
}
- (void)buttonTouched
{
self.currentIndex++;
if ( self.currentIndex >= self.abcs.count ) {
self.currentIndex = 0;
}
[self updateButtonText];
}
- (void)updateButtonText
{
[self.button setTitle:self.abcs[self.currentIndex] forControlState:UIControlStateNormal];
}

Simplest solution would be to put a static variable which keeps tracking index
-(void)createLoginBioButton
{
authButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[authButton setBounds:CGRectMake(300,300, 150, 150)];
[authButton setCenter:CGPointMake(150, 240)];
[self.view addSubview:authButton];
[authButton setEnabled:true];
[authButton setTitle:#"A" forState:UIControlStateNormal];
[authButton setFont:[UIFont systemFontOfSize:70]];
[authButton addTarget:self action:#selector(displayABC:) forControlEvents:UIControlEventAllTouchEvents];
}
-(void)displayABC:(id)sender
{
static int index = 0;
NSString *path = [[NSBundle mainBundle] pathForResource:#"ABC" ofType:#"plist"];
NSArray *ABCArray = [NSArray arrayWithContentsOfFile:path];
if(index < [ABCArray count])
[authButton setTitle:[ABCArray objectAtIndex:index] forState:UIControlStateNormal];
index++;
}

Related

How to create buttons that add integers to a Mutable Array?

I am quite new to iOS programming. Can anyone help me on how to create two buttons (button 1 and button 2) that add integers (integer 1 and integer 2) to a Mutable array when each button is clicked?
Means that when Button 1 is clicked, integer 1 is added to the mutable array, and when integer 2 is clicked, integer 2 will be added to the mutable array. I understand we need to create an instance of the mutable array before we can use the array, but I'm not sure where is the best place to do that?
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSMutableArray *inputArray = [[NSMutableArray alloc] init];
}
- (IBAction)Button1:(id)sender {
int _userinput = 1;
NSNumber *userinput = [NSNumber numberWithInteger:_userinput];
[self.inputArray addObject:userinput];
NSLog(#"%#", self.inputArray[0]);
}
You can create instance variable of NSMutableArray and two buttons with setting tag value and on clicking the same you can add it to array.like that below:-
- (void)viewDidLoad
{
[super viewDidLoad];
self.mutArr=[NSMutableArray array];
NSUInteger j=0;
for(NSUInteger i=0; i<2; i++)
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self
action:#selector(buttonClicked:)
forControlEvents:UIControlEventTouchUpInside];
[button setTitle:[NSString stringWithFormat:#"%# %ld",#"Button",i+1] forState:UIControlStateNormal];
button.frame = CGRectMake(80.0+j, 210.0, 160.0, 40.0);
[self.view addSubview:button];
button.tag=i+1;
j=100;
}
}
-(void)buttonClicked:(id)sender
{
[self.mutArr addObject:#([sender tag])];
NSLog(#"%#",self.mutArr);
}

buttons check the correct answer objective-c

I have one UIViewController and inside I have NSArray that I put my correct answer,and also I have 3 buttons, and 3 NSArray for their titles, I want to check if my buttons title was equal to the correct answer then goes to the correct page else goes to the wrong page
would you please help me to this implementation:
Thanks in advance!
Here is my code:
NSString *correctOne = #"test1";
NSString *correctTwo = #"test2";
NSString *correctThree = #"test3";
NSString *correctFour = #"test4";
NSString *correctFive = #"test5";
NSString *correctSix = #"test6";
NSString *correctSeven = #"test7";
NSString *correctEight = #"test8";
correctComments = [[NSArray alloc] initWithObjects: correctOne, correctTwo, correctThree,
correctFour, correctFive, correctSix, correctSeven, correctEight, nil];
int rand = arc4random()%8;
NSString *correct = [correctComments objectAtIndex:rand];
[test setTitle:(firstAnswer) forState:UIControlStateNormal];
[test setTitleColor:[UIColor blueColor] forState:UIControlStateSelected];
[test setTag:0];
[ansONE setTitle:(secondAnswer) forState:UIControlStateNormal];
[ansONE setTitleColor:[UIColor blueColor] forState:UIControlStateSelected];
[ansONE setTag:1];
[ansTWO setTitle:(threeAnswer) forState:UIControlStateNormal];
[ansTWO setTitleColor:[UIColor blueColor] forState:UIControlStateSelected];
[ansTWO setTag:2];
- (IBAction)suivant:(id)sender {
//MY Question is how should I check my button title and correctComments
}
- (IBAction)suivant:(id)sender {
UIButton *button = (UIButton *)sender;
int correctIndex = ...;
BOOL thisIsTheCorrectButton = (button.tag == correctIndex);
// Do whatever
}
At first you have to store correct answer from your code snippet to a property:
self.correctAnswer = correct;
Then do the comparision of those strings:
- (IBAction)suivant:(UIButton *)sender {
// You wanted to check for title:
if ([sender.currentTitle isEqualToString:self.correctAnswer]) {
// Correct...
}
else {
// Wrong...
}
}

Passing an object to selector action

Ok simple question but can't find an answer.
I'v got a button to save information in my app.
I have
NSMutableArray *textFields = [[NSMutableArray alloc] initWithCapacity:5];
UITextField *textField = nil;
This is the information i want to save, i'v got 5 textfields in textFields mutablearray.
[save addTarget:self action:#selector(saveInfo)
forControlEvents:UIControlEventTouchUpInside];
and
-(void)saveInfo {
[[[NSUserDefaults standardUserDefaults] setValue: ????? forKey:#"Phone"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
The question is how to access and get information from like textFields[1].text in my saveInfo void ?
Ok To get things a little bit clearer i'v added the whole class. its not very big, and maybe someone could see thats the problem with my implementation .
#implementation Settings
- (id)init: (TableViewController*) TableControll {
NSMutableArray *textFields = [[NSMutableArray alloc] initWithCapacity:5];
UITextField *textField = nil;
for (int i = 0; i < 3; i++) {
textField = [[UITextField alloc] initWithFrame:CGRectMake(0.0f, 0.0f+(i*35), 120.0f, 30.0f)];
textField.backgroundColor = [UIColor whiteColor];
[textField setBorderStyle:(UITextBorderStyleRoundedRect)];
[TableControll.view addSubview:textField];
[textFields addObject:textField];
[textField release]; textField = nil;
}
UITextField *textName = textFields[0];
textName.placeholder = #"Vardas";
UITextField *textNo = textFields[1];
textNo.placeholder = #"Telefonas";
textNo.keyboardType = UIKeyboardTypeNumberPad;
UITextField *textPin = textFields[2];
textPin.keyboardType = UIKeyboardTypeNumberPad;
textPin.placeholder = #"Pin";
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(150, 20, 160, 30);
[button setTitle:#"Advanced settings" forState:UIControlStateNormal];
[TableControll.view addSubview:button];
UIButton *save = [UIButton buttonWithType:UIButtonTypeRoundedRect];
save.frame = CGRectMake(150, 60, 160, 30);
[save setTitle:#"Save settings" forState:UIControlStateNormal];
[TableControll.view addSubview:save];
[button addTarget:self action:#selector(goAdvanced)
forControlEvents:UIControlEventTouchUpInside];
[save addTarget:self action:#selector(saveInfo)
forControlEvents:UIControlEventTouchUpInside];
return self;
}
-(void)goAdvanced {
AppDelegate *newControll = (AppDelegate*)[UIApplication sharedApplication].delegate;
[newControll ChangeController];
}
-(void)saveInfo {
for(int i=0;i<5;i++) {
UITextField *tempTxtField=[_textFields objectAtIndex:i];
NSLog(#"do it %#",tempTxtField.text);
}
}
#end
What you'd want to do if you are using interface builder is create a bunch of IBOutlet for your textfields instead of keeping them in an array. Check out this: tutorial
Now it looks like you're creating things by hand, so in this case, you probably just want to declare your array as #property so it can be accessed by your save method.
To access the text property of a UITextField from your array you would write:
((UITextField *)[textFields objectAtIndex:1]).text
If you want to access the all textfield,
for(int i=0;i<[textFields count];i++) {
UITextField *tempTxtField=[textFields objectAtIndex:i];
NSlog(#"%#",tempTxtField);
}
-(void)saveInfo {
NSMutableArray *tempArr = [NSMutableArray array];
for(int i = 0; i < [textFieldsArray count]; i++){
[tempArr addObject:[(UITextField*)[textFieldsArray objectAtIndex:i]text]];
}
[[[NSUserDefaults standardUserDefaults] setValue:tempArr forKey:#"Phone"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
I'm not entirely sure I understand your question, but this is what I would do in your place. Instead of creating an array to hold each of the textfields, I'd just assign them a custom tag. Any number will work (although avoid zero since that's the default tag on all views). So your init method would look like this:
for (int i = 0; i < 3; i++) {
textField = [[UITextField alloc] initWithFrame:CGRectMake(0.0f, 0.0f+(i*35), 120.0f, 30.0f)];
textField.backgroundColor = [UIColor whiteColor];
textField.tag = (i+1);
[textField setBorderStyle:(UITextBorderStyleRoundedRect)];
[TableControll.view addSubview:textField];
[textField release]; textField = nil;
}
Then in the code that you want to reference the text field, you'd retrieve the view by its tag, making sure to cast it as UITextField.
-(void)saveInfo {
for(int i=0;i<5;i++) {
UITextField *textField = nil;
UIView *view = [self.view viewsWithTag:i];
if ([view isKindOfClass:[UITextField class]]) {
textField = (UITextField *) view;
NSLog(#"do it %#",textField.text)
}
}
}
NOTE: I'm referencing self.view but you'll need to reference TableControll.view. You'll need to retain a reference to it somewhere in your code. Also, I'd recommend your start using ARC.
Hope that helps! Good luck!

Property retain in ios

Ok simple question but can't find an answer..
I need to pass my viewcontroller to an method "saveinfo" within a class which is called when the button is pressed, how to make viewcontroller visible to "saveinfo" method so i can use it there?
Ok i'll add the whole class. Basicaly I need to get the textfield information when the button is pressed. But i can't get access to textFields nor TableControll variables in my saveinfo method.
#implementation Settings
- (id)init: (TableViewController*) TableControll {
NSMutableArray *textFields = [[NSMutableArray alloc] initWithCapacity:5];
UITextField *textField = nil;
for (int i = 0; i < 3; i++) {
textField = [[UITextField alloc] initWithFrame:CGRectMake(0.0f, 0.0f+(i*35), 120.0f, 30.0f)];
textField.backgroundColor = [UIColor whiteColor];
[textField setBorderStyle:(UITextBorderStyleRoundedRect)];
[TableControll.view addSubview:textField];
[textFields addObject:textField];
[textField release]; textField = nil;
}
UITextField *textName = textFields[0];
textName.placeholder = #"Vardas";
UITextField *textNo = textFields[1];
textNo.placeholder = #"Telefonas";
textNo.keyboardType = UIKeyboardTypeNumberPad;
UITextField *textPin = textFields[2];
textPin.keyboardType = UIKeyboardTypeNumberPad;
textPin.placeholder = #"Pin";
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(150, 20, 160, 30);
[button setTitle:#"Advanced settings" forState:UIControlStateNormal];
[TableControll.view addSubview:button];
UIButton *save = [UIButton buttonWithType:UIButtonTypeRoundedRect];
save.frame = CGRectMake(150, 60, 160, 30);
[save setTitle:#"Save settings" forState:UIControlStateNormal];
[TableControll.view addSubview:save];
[button addTarget:self action:#selector(goAdvanced)
forControlEvents:UIControlEventTouchUpInside];
[save addTarget:self action:#selector(saveInfo)
forControlEvents:UIControlEventTouchUpInside];
return self;
}
-(void)goAdvanced {
AppDelegate *newControll = (AppDelegate*)[UIApplication sharedApplication].delegate;
[newControll ChangeController];
}
-(void)saveInfo {
for(int i=0;i<5;i++) {
UITextField *tempTxtField=[_textFields objectAtIndex:i];
NSLog(#"do it %#",tempTxtField.text);
}
}
#end
just add the NSMutableArray as ivar to your class:
#implementation TableControll {
NSMutableArray *_textFields;
}
- (id)init: (TableViewController*) tableControll {
_textFields = [[NSMutableArray alloc] initWithCapacity:5];
//init the textfields
//and add it as subview
}
// skipping the rest of the implementation
-(void)saveInfo {
for(int i=0;i<5;i++) {
UITextField *tempTxtField=[_textFields objectAtIndex:i];
NSLog(#"do it %#",tempTxtField.text);
}
}
#end
you should check if you could reuse the UITextFields or have to init the NSMutableArray every time again. It seems you don't use ARC, but you shouldn't write something like [textField release]; textField = nil;. You want to release the object to decrement the counter, but do not set it to nil (except in dealloc).

Why this brings about SIGABRT error?

I have some sources below.
- (void)Button:(UIButton *)button {
NSString *imageName = ((UIButton *)[self.view viewWithTag:button.tag]).titleLabel.text;
}
- (void)viewDidLoad {
NSMutableArray *_array = [[NSMutableArray alloc] init];
NSInteger iCount = [_array count];
for (i = 0; iCount > i; i++) {
UIButton *btn = [[UIButton alloc] init];
btn.titleLabel.text = [[_array objectAtIndex:i] objectForKey:#"FILE"];
btn.tag = i;
[btn addTarget:self action:#selector(Button:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
[btn release];
}
When I access Button method with 0 index tag, I get SIGABRT error.
What can I do ?
Read your console output properly, by default every view has the tag '0', so it can be crashed because it is taking some other view besides of uibutton, and may be that view don't not have the titleLabel property.Because it is the property of UIButton.