I want to have one UIButton that will change the text of a label in a series. For example, I may have a label that says hello.
Then when i push a button, it will change to, What's up?.
But then a second tap of the same button will change the label to Nuttin' much!.
I know how to make the text of a label change once, but how do I change it many times with the same button? Preferably, anywhere around 20 to 30 separate texts.
Thank you in advance! :D
That's pretty open ended. Consider adding a property to your class which is an index into an array of strings. Each time you push the button increment the array (modulo size of array) and use the corresponding string to update the button. But there are a lot of other ways you could do this...
What happens when the app runs out of phrases? Start over? The typical approach would look like this.
#property (strong, nonatomic) NSArray *phrases;
#property (assign, nonatomic) NSInteger index;
- (IBAction)pressedButton:(id)sender {
// consider doing this initialization somewhere else, like in init
if (!self.phrases) {
self.index = 0;
self.phrases = #{ #"hello", #"nuttin' much" }; // and so on
}
self.label.text = self.phrases[self.index];
self.index = (self.index == self.phrases.count-1)? 0 : self.index+1;
}
In the viewDidLoad method, create an array with strings to hold the labels. Then create a variable to keep track of which object should be set as the current label. Set the initial text:
NSArray *labelNames = [[NSArray alloc] initWithObjects:#"hello",#"what's up?", #"nuttin much"];
int currentLabelIndex = 0;
[label setText:[labelNames objectAtIndex:currentLabelIndex]];
Then in the method that gets called when the button is tapped, update the text and the index.
- (IBAction) updateButton:(id)sender {
// this finds the remainder of the division between currentLabelIndex+1 and labelNames.count. If it is less than the count, its just the index. If its equal to the count we go back to the beginning of the array.
currentLabelIndex = (currentLabelIndex+1)%labelNames.count;
[label setText:[labelNames objectAtIndex:currentLabelIndex]];
}
Related
Okay, so I don't really know if NSDictionary is the correct approach to this, but I am using a fade animation to take different groups of buttons on and off a screen. I want to "compartmentalize" them, so to speak, into different groups so I can do this in one or two lines without having to rewrite all the buttons names every time (there are a good amount). Any ideas on how to do this?
[UIView animateWithDuration: 1.5
animations: ^(void)
{
//As an example i just called them button1, button2, etc.
self.button1.alpha = 1;
self.button2.alpha = 1;
self.button3.alpha = 1;
self.button4.alpha = 1;
self.button5.alpha = 1;
}
];
I included the above as an example of what I am asking. Is there a way to put all the buttons in an NSDictionary and write one line (where the buttons are currently located) that changes all of their alphas?
The preferred mechanism nowadays for buttons you've added in Interface Builder would be an IBOutletCollection:
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *buttons;
Clearly, in Interface Builder you would connect the individual buttons to the outlet collection. For a discussion of IBOutletCollection, see NSHipster's IBAction / IBOutlet / IBOutlet​Collection article.
If you're not using Interface Builder, but rather have created these buttons programmatically, you could just have an NSArray:
#property (strong, nonatomic) NSArray *buttons;
Which you'd then populate yourself:
self.buttons = #[self.button1, self.button2, self.button3, self.button4, self.button5, self.button6];
Regardless of how you build this array (either outlet collection or manually populated), you can then iterate through that array as you update a property of the buttons:
for (UIButton *button in self.buttons) {
button.alpha = 1;
}
Or, even simpler, you can update all of them with setValue:forKey::
[self.buttons setValue:#1 forKey:#"alpha"];
You can use button tags to accomplish this. Set the same tag for multiple buttons (your groups) and do:
button.tag = 1;
then:
for (UIButton *btn in button) {
if(btn.tag == 1)
{
// do something
break; // don't need to run the rest of the loop
}
}
I'm following a tutorial to create a simple game where you tap a button and the the game counts how many times you have pressed the button as you go along. The score is displayed on screen in the form of a label.
I can make it so that when you press the button the label text changes to say 'Pressed!'. But then i can not get the label to change when i try to add the changing score with a format specifier.
-(IBAction)buttonPressed{
count ++;
//scoreLabel.text =#"pressed";
scoreLable.text = [NSString stringWithFormat:#"Score\n%i", count];
}
Any help would be greatly appreciated. Thanks!
You may not have your label set up for multiple lines of text. Try getting rid of the "\n" in your format string. Other than that, you need to tell us what happens. Have you put a breakpoint to make sure your button IBAction is being called? Have you checked to make sure "scoreLable" (sic) is not nil? The devil is in the details.
-(IBAction)buttonPressed : (id) sender{
UIButton * btnPressed = (UIButton *)sender;
int buttonValue = [[btnPressed titleForState:UIControlStateNormal] intValue];
NSLog(#"Button value = %d", buttonValue);
//scoreLabel.text =#"pressed";
scoreLable.text = [NSString stringWithFormat:#"Score\n%i", count];
}
First You Can Set static int count = 0;
I have a few UILabels, any one of which will update according to the index of an NSArray index they represent. I thought of selecting them by their tag
self.displayLabel.tag = myArray[index];
but that changes the tag value to whatever my array is holding at the moment
Using a dictionary for whatever tricks it offers instead of an NSArray doesn't help because i still have to select the correct matching label. This is the effect i want to achieve.
self.|mySelectedLabel|.text = myArray[index];
what should i put in |mySelectedLabel| to get the one i'm looking for?
I'm almost ashamed to ask at my reputation level, but this is stymie-ing me
every search only turns up how to set Labels and change, not the process of selecting
Assuming you have set the tags to the appropriate index to match your
array indices you can use [self.view viewWithTag:index];
Why are you not setting the tag with:
self.displayLabel.tag = index;
Also, you could just loop though an array of labels and find the right one:
for (UILabel *label : labelArray) {
if (label.tag == index) {
label.text = #"I found you!";
}
}
Rather than using tags you can refer to your specific textfields by reference:
// Create an array to hold your textfields
NSMutableArray *textFields = [NSMutableArray array]
// Create your textfields and add them to the array
UITextField *textField;
for (NSUInteger idx = 0: idx++; idx < numberOfTextFieldsYouWant) {
textField = [UITextField alloc] initWithFrame:<whateverYouWant>];
[textFields addObject:textField];
}
Since you are adding the objects to an array, rather than using the tag value 0, 1, 2... you can just access it by it's index in the array
So, for what you want to do you can just do:
textfields[index].text = myArray[index];
It's a lot cleaner, doesn't rely on magic tags, and you have an array of all your dynamic textfields that you can remove, or change in one place.
I think tags are vastly overused, and they aren't necessary in most cases.
Just letting you know I reframed the problem and this eventually worked for me without having to use an array
( with endless experimenting, I sort of bumped into it so I don't know if it constitutes good technique )
the desired label corresponding to the bag weight ( one of a number possible ) displays the right update
- (IBAction)acceptWeight:(UIButton *)sender {
int tempValue = (int) currentWeight;
// current weight comes from a UISegementedController
for (UILabel *labels in self.view.subviews)
{
if (labels.tag == currentWeight)
{
bags[tempValue]++;
labels.text = [NSString stringWithFormat:#"%i",bags[tempValue]];
}
}
totalKilo = totalKilo + (int)currentWeight;
self.totalKilo.text = [NSString stringWithFormat:#"%d",totalKilo];
}
I have twelve text fields as you can see below:
IBOutlet UITextField *ce_1;
IBOutlet UITextField *ce_2;
IBOutlet UITextField *ce_3;
....
IBOutlet UITextField *ce_12;
All I have to do is to set an existing object in an array in each of the variables that are responsible for the text fields, I'm currently doing as follows:
ce_1.text = myArray[1];
ce_2.text = myArray[2];
ce_3.text = myArray[3];
....
ce_12.text = myArray[12];
Not to be writing a lot, I thought I'd put this in an automated way within a loop as follows:
for(i=1;i<13;i++){
ce_[i].text = myArray[i];
}
But this command does not work the way I expected, so I would like your help to try to solve my idea and put it into practice, is there any way of doing this?
Research and start using IBOutletCollection. It will give you an array of text fields that you can build in your storyboard XIB.
Note that you may need to consider the order of the array, and that you might want to sort it (possibly based on the tag of each view).
Technically, you could use string formats and KVC to do what you're currently trying to but it is far from ideal.
You can't just replace ce_1 ce_2 ce_3 with ce_[i] it doesn't work that way. You can only use [number] with an nsarray variable (or decendents).
for example:
NSArray* myArray = #[#1];
NSLog(#"%#", myArray[0]);
You might want to look into IBOutletCollection in order to achieve something similar to what you're looking for.
However, contrary to other answers here IBOutletCollection are ordered by how you link them in the interface builder.
Refer to this for IBOutletCollections: How can I use IBOutletCollection to connect multiple UIImageViews to the same outlet?
You can use IBOutletCollection. You can also use key-value coding:
for(NSUInteger i = 0; i < 13; i++)
{
[[self valueForKey:[NSString stringWithFormat:#"ce_%u", i]] setText: myArray[i]];
}
This will give you what you want.
The way I like to handle these situations is creating a temporary array containing all the text fields:
NSArray *allFields = #[_ce_1, _ce_2, _ce_3, ...];
NSInteger i = 0;
for (UITextField *tf in allFields)
{
tf.text = myArray[i];
i++
}
IBOutletCollection also work but sometimes it gets hard to figure out when you come back to your project which label is #3 or #5 and such... I find this works better for me usually :)
Is it possible? I have an array of buttons created in an void and I want to move one when a neighbouring one is called in the buttonTapped void. I have no trouble moving the button thats pressed because it is the sender, but I also need to move the one next to it and can't seem to get it to move. Each button in the array has a tag value so they're unique.
Thanks
Reasonable intuitive assumption: you generated the buttons so that they are ordered in the array...
- (void)moveButton:(UIButton *)sender // whatever
{
NSUInteger idx = [buttonArray indexOfObject:sender] + 1;
UIButton *nextButton = idx < buttonArray.count ? [buttonArray objectAtIndex:idx] : nil;
// do something with `nextButton`
}