How to create buttons that add integers to a Mutable Array? - objective-c

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);
}

Related

UIButton title replacement with each press

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++;
}

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!

How to animate randomly each button displayed using for loop in ios

Hi I have a list of buttons which I am displaying using for loop. I want to animate random button can any one help me. Here is the code which I am trying, with this code only last button is animating continuously.
-(void)arrangeFavouriteWords
{
[buttonsArray removeAllObjects];
buttonsArray = [[NSMutableArray alloc]init];
for(int i=0;i<count1;i++)
{
WordObject *favObj = [databaseArray objectAtIndex:i];
float height = [MainViewController calculateHeightOfTextFromWidth:favObj.wordName :fontValue : buttonWidth :UILineBreakModeCharacterWrap];
myButton = [[MyCustomButton alloc]initWithIdValue:favObj.wordName];
myButton.backgroundColor = [UIColor clearColor];
myButton.frame = CGRectMake(0,yCoordinate,buttonWidth,height);
myButton.tag = i;
[myButton.titleLabel setFont:fontValue];
[myButton setTitleColor:color forState:UIControlStateNormal];
[myButton setTitle:favObj.wordName forState:UIControlStateNormal];
[myButton addTarget:self action:#selector(wordClicked:) forControlEvents:UIControlEventTouchUpInside];
myButton.contentHorizontalAlignment = NO;
[buttonsArray addObject:myButton];
[displayView addSubview:myButton];
[myButton release];
yCoordinate = yCoordinate + height;
}
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:(0.5) target:self selector:#selector(onTimer) userInfo:nil repeats:YES];
}
-(void)onTimer
{
int randomIndex = arc4random() % [buttonsArray count];
printf("\n the random index is :%d",randomIndex);
myButton.tag = randomIndex;
if(randomIndex == myButton.tag)
{
CABasicAnimation *theAnimation;
theAnimation=[CABasicAnimation animationWithKeyPath:#"transform.scale"];
theAnimation.duration=1.0;
//theAnimation.repeatCount=HUGE_VALF;
theAnimation.autoreverses=YES;
theAnimation.fromValue=[NSNumber numberWithFloat:1.25f];
theAnimation.toValue=[NSNumber numberWithFloat:1.0f];
[myButton.layer addAnimation:theAnimation forKey:#"transform.scale"];
}
}
This is your problem:
myButton.tag = randomIndex;
if(randomIndex == myButton.tag)
You see, when you have a pointer to an instance (in this case, a UIButton named myButton), it holds only one instance at a time, which must be the "last button" that you describe. Instances in Objective-C (or any other language for that matter), do not magically morph into the object you expect them to be within the method they would be most convenient in. You need to actually assign myButton to a different instance, or reference that other instance instead.
This is further complicated by the fact that you are setting, then immediately checking the same value (.tag), which is akin to saying "X is now 3. If X is 3, then...". You need a proper reference to every button, and some place to store them all (say, an NSArray). That way, you can use the random index to retrieve the button from the array with objectAtIndex:.
What's myButton in your -onTimer method? I guess it'd be better to take object from your buttonsArray and work with it:
...
int randomIndex = arc4random() % [buttonsArray count];
UIButton *animatableButton = [buttonsArray objectAtIndex:randomIndex];
...

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.

Accessing NSMutableArray Difficulties

I am trying to build an NSMutableArray each time a button is pressed. I am using NSLog to check the array count after each button pressed and the value is zero. THe code is below.
ProjectViewController.h
NSMutableArray *numberQuery
...
#property (nonatomic, retain) NSMutableArray *numberQuery;
ProjectViewController.m
- (void)makeButtons{
UIButton * pickButton;
int y_plot = 150;
int x_plot = 70;
int z = 0;
for(int y = 1; y < 10; y++)
{
for(int x = 1; x < 5; x++){
z++;
pickButton = [UIButton buttonWithType:UIButtonTypeCustom];
pickButton.frame = CGRectMake(x*x_plot, y_plot, 60, 40);
[pickButton setBackgroundImage:[UIImage imageNamed:#"btnUnselected.png"] forState:UIControlStateNormal];
[pickButton addTarget:self action:#selector(digitClick:) forControlEvents:UIControlEventTouchUpInside];
[pickButton setTitle:[NSString stringWithFormat:#"%d",z] forState:UIControlStateNormal];
pickButton.titleLabel.textColor = [UIColor blackColor];
pickButton.tag = z;
[self.view addSubview:aButton];
}
y_plot=y_plot+45;
}
}
//************************
- (void)digitClick:(id)sender{
UIButton * chosenButton =(UIButton *)sender;
if ([sender isSelected] ==FALSE) {
[sender setSelected:TRUE];
[chosenButton setBackgroundImage:[UIImage imageNamed:#"btnSelected.png"] forState:UIControlStateNormal];
chosenButton.titleLabel.textColor = [UIColor whiteColor];
if([queryNumbersX count]<6){
[self numberSearchArray:chosenButton.tag];
}
}
else
{[sender setSelected:FALSE];
[chosenButton setBackgroundImage:[UIImage imageNamed:#"btnUnselected.png"]forState:UIControlStateNormal];
chosenButton.titleLabel.textColor = [UIColor blackColor];
}
forState:UIControlStateNormal];
NSLog(#"clicked button with title %d",chosenButton.tag);
}
//************************
-(void) numberSearchArray:(NSInteger)newNumber;
{
[self.numberQuery addObject:[NSNumber numberWithInt: newNumber]];
NSLog(#"numberSearchArray %d - count %d",newNumber, [self.numberQuery count]);
}
Am I using the NSMutableArray in the right manner...declaration?
This is the code in the viewDidLoad method
NSMutableArray *numberQuery = [[NSMutableArray alloc] initWithObjects:nil];
Although I have the array declared int he header file, It seems as though I cannot access it outside of the method in which it was allocated.
#property (nonatomic, retain) NSMutableArray *numberQuery;
You must balance that with
#synthesize numberQuery;
in the .m
and the correct creation would be
self.numberQuery = [NSMuatableArray arrayWithCapacity:someNumber];
By doing this
NSMutableArray *numberQuery = [[NSMutableArray alloc] initWithObjects:nil];
You are not using your #property you are creating a new variable, this is why you get the warning that your variable is not use, because it's scope is actually just the viewDidLoad method instead of the object.
It looks like that you have never alloced numberQuery. So it is always nil and thus addObject method is ignored. You need to alloc this in init (or any suitable place you like) and release in dealloc (or in other suitable place).