How to remove a specific object from an array [closed] - ios

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
So I'm currently making a calorie tracker. In this app, you enter the recent meal you ate, and the amount of calories in that meal. Then you press the "add" button. This button will save the data to a TableView called HistoryTableViewController. To check if the person has left a textfield blank, I have 3 "if statement". One looks like this:
if ([[self.amountText.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] < 1)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Warning!" message:#"You have not entered the amount of Calories!" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
[amountHistory removeObjectAtIndex:0];
}
There is one line of code that I know is wrong which is the
[amountHistory removeObjectAtIndex:0];
I don't necessarily want to remove the first object on the tableview, I just want to make sure that the item doesn't get added.
Thanks in advance.
EDIT:
I add an object to the array at the top of the if statements:
total+= self.amountText.text.intValue;
self.totalLabel.text = [NSString stringWithFormat:#"%d", total];
NSNumber *calorieNumber = [NSNumber numberWithInt:self.amountText.text.intValue];
NSString *foodString = nameOfTheFood.text;
NSString *historyString = [NSString stringWithFormat:#"%# Calories in %#", calorieNumber, foodString];
[amountHistory addObject:historyString];

Sounds like you are thinking about it from the wrong angle.
Instead of adding the item to your array and then removing it if it is invalid, you should ensure the item is only added when it is valid.
So in your method you would only add the item at the end, after all validation has passed. You would add early return's in your if statements if the any validation fails so that you don't reach the code that adds the item to the array

The answer to your subject:
How to remove a specific object from an array
is
[array removeObject:obj];
Note, this uses the isEqual message on the object to determine equality. If you want specific object equality, use removeObjectIdenticalTo: instead.
Source: Apple Docs on NSMutableArray

If you are looking to remove the last item in the array use:
[amountHistory removeLastObject];
But if your issue is that you don't want to add blank items to the array why not check if they are blank before adding them?

You can only remove objects from an array if you are using NSMutableArray. Have a read of the NSMutableArray Class Reference

Related

Updating UILabel.Text inside of a for loop after a button is pressed

I have a UIViewController, and in that I have an array of questions that I pull from a sqlite3 query. I am then using a for loop to iterate through each question in the array to change the UILabel.text to display the question on the screen. This is actually working for the first question in the array!
I then have four buttons for answers. I want to make it so if one of the buttons is pressed, the answer is saved and the next question in the loop updates the UILabel.text.
The four answers never change as it is more of a survey than answers, so one of the answers is "I agree" or "disagree", so the button text never changes.
Is this possible?
I have been on here and Google to find a way to link the button pressed with completing each iteration of the loop without any luck.
Why are you iterating through questions and changing UILabel's text? Shouldn't be it changed only on tapping one of the survey buttons?
If I got you correctly, you should do following:
1) Declare three properties in your controller: NSArray *questions, NSMutabelArray *answers, NSInteger currentIndex;
2) Init/alloc them in viewDidLoad (except currentIndex, of course, set it to 0).
3) Fill up questions array with your question strings.
4) Set text to UILabel, label.text = questions[currentIndex];
5) create IBAction method and link it to all survey buttons.
6) in IBAction method, insert button's title to answers array and show next question.
- (void)viewDidLoad {
[super viewDidLoad];
self.questions = {your questions array};
self.answers = [[NSMutableArray alloc] init];
self.currentIndex = 0;
}
- (IBAction)btnClicked:(id)sender {
UIButton *btn = (UIButton *)sender;
NSString *title = btn.titleLabel.text;
[self.answers addObject:title];
currentIndex++;
label.text = questions[currentIndex];
}
I hope you will understand the code.
In short, yes this is possible.
You'll first want to keep track of the question that your user is currently on. You can do this by storing an index in an instance variable or, if you plan on allowing the user to open the app and start from where they left off, you can use NSUserDefaults, which writes to disk and will persist.
// In the interface of your .m file
int questionIndex;
// In viewDidLoad of your controller, however this will start for index 0, the beginning of your questions array
questionIndex = 0
By storing the index in NSUserDefaults, you can grab it in ViewDidLoad, and start from where the user last left off:
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:questionIndex] forKey:#"questionIndex"];
To store your answer, you could add a method for your buttons called answerTapped:,
- (void)answerTapped:(UIButton *)answerButton
{
// Grab the answer from the text within the label of the button
// NOTE: This assume your button text is the answer that you want saved
NSString *answer = answerButton.titleLabel.text;
// You can use your questionIndex, to store which question this answer was for and you can then take the answer and store it in sqlite or where you prefer...
}
You can add this method to your buttons like so
[answerButton addTarget:self action:#selector(answerTapped:) forControlEvents:UIControlEventTouchUpInside];
You could then write a method to increment questionIndex now that an answer button has been pressed.
- (void)incrementQuestionIndex
{
// Increment index
questionIndex += 1;
// Update and save value in UserDefaults
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:questionIndex] forKey:#"questionIndex"];
}
You could then call a separate, final method to update the question label.
- (void)updateQuestionLabel
{
// Grab the question using the index (omit this line and go straight to the next if storing the index in an iVar)
questionIndex = [[[NSUserDefaults standardUserDefaults] objectForKey:#"questionIndex"] integerValue];
// Grab the question using the index. Assumes you have a questions array storing your questions from sqlite.
NSString *question = [questions objectAtIndex:questionIndex];
// Update the question UILabel
[questionLabel setText:question];
}

Objective C NSArray [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I would like to append data to NSArray and than get count of data in NArray and retrieve data at specific index.
I am adding data as follows:
NSArray *oneInfo = #[
#{#"trackTime" :theTrack[#"seconds"],
#"trackPrice":theTrack[#"price" ],
#"trackWait" :theTrack[#"wait" ]
}
];
Your array is an array literal which means it is immutable. In order to make an array that you can change, do this:
NSArray *oneInfo = #[#{#"trackTime":theTrack[#"seconds"],#"trackPrice":theTrack[#"price"],#"trackWait":theTrack[#"wait"]}];
NSMutableArray* somethingICanChange = [oneInfo mutableCopy];
[somethingICanChange addObject: moreData];
Note that, if you are not using ARC (why not?), somethingICanChange is an array that you own and needs to be released or autoreleased when you are done with it.
You can not append NSArray you have to create NSMutableArray for appending and other changes your need.
oneInfo = [oneInfo arrayByAddingObject: something];

What's wrong with this code? I'm trying to change a label text with NSString and NSLog [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm trying to do something very simple, I'm trying to change a label to "I like to say hi" by clicking a button. I already know how to do it without NSString but I wanted to make it more harder, but I can't find what's wrong with this code. It's not working.
- (IBAction)button:(id)sender{
NSString *hi = #"hi";
_label.text = NSLog(#"I like to say %#", hi);
}
I'm also trying to do something even more complicated and use a void statement like this. Would this work, and if not what's wrong with it?
- (void)num{
int num = 42;
}
- (IBAction)button:(id)sender{
_label.text = NSLog(#"I like to say %i", num);
}
Why are you trying to use NSLog for this? That's for showing messages in the log.
You want NSString stringWithFormat:.
_label.text = [NSString stringWithFormat:#"I like to say %#", hi);
What you have won't even compile since the NSLog function does not return an NSString value.
NSLog is a function with a void return type, which means it does not return any value, so you can't use it to assign the value of a property. It is used only for printing messages to the debugging console or device logs. What you are probably looking for is stringWithFormat:
_label.text = [NSString stringWithFormat:#"I like to say %#", hi];
This is a method of the NSString class. It constructs strings similar to NSLog, but it actually returns a new NSString value that can be assigned to properties and so on.
Read its documentation here. You will be using this and other NSString methods all the time.
Regarding your other code:
If you want to construct a method named num that produces a value you can use elsewhere, you need to declare the type of the value it returns, instead of using void:
- (int)num{
return 42;
}
Now num is a proper instance method. You will need to tweak your code to be able to access this method correctly:
- (IBAction)button:(id)sender{
_label.text = [NSString stringWithFormat:#"I like to say %i", [self num]];
}
Here you are sending the message num to self. The keyword self is, loosely speaking, a reference to the current object instance. So [self num] will invoke the num method you have defined, and return its value. You may want to read Programming with Objective-C to learn more about these concepts.

UIAlertView with timer [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I'm trying to make a UIAlertView with a timer. For example: The user sets a time, the user taps a button, a UIAlertView pops up and in the alertView there is a timer showing how long the user has to wait before an action will start.
When searching the web I only found how to show how much time has passed. Is there a way to update the UIAlertView every second to show the timer? After the time has passed, the UIAlertView needs to be dismissed and a void has to be called.
try like it.
UIAlertView *autosaveAlert = [[UIAlertView alloc]initWithTitle:#"Close" message:#"Autosave in (%d) seconds" delegate:self cancelButtonTitle:#"Press to cancel" otherButtonTitles:nil];
[autosaveAlert show];
for(int i = 10; i>=0; i--){
NSString *tmp = #"Close in (%d) seconds";
NSString *str = [NSString stringWithFormat:tmp, i];
[autosaveAlert setMessage:str];
CFRunLoopRunInMode(kCFRunLoopDefaultMode,1, false);
}
[autosaveAlert dismissWithClickedButtonIndex:0 animated:TRUE];
Yes, you can keep a pointer to the alert view & modify its message, title & dismiss it with any button index you choose. Refer to the UIAlertView class reference document for proper method names.

NSArray value to NSString [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have an NSArray declared like this in my ViewDidLoad
animalz = [NSArray arrayWithObjects:#"rabbit",#"deer",#"ox", #"horse", #"cow", nil]; and I have a UIView subclass that I wrote which takes an NSString and rearranges it. The user presses a button and the number associated with the button is the number in the array that I need (Ex. if the number is three then I would need the value "horse" but if the button was 4 then I would need "cow"); Currently these numbers come in the form of long int and I can't get the corresponding value in the nsarray. I tried doing:
selectedani //this is the long int that represents the button
int indexani = [animalz objectAtIndex:selectedani];
NSString *anistr = [NSString stringWithFormat:#"%i",indexani];
[self rearrange:btistr];
This doesn't give me any compiler warnings or errors but when I press the button , the app crashes. What am I doing wrong and how can I fix it?
selectedani //this is the long int that represents the button
NSString *anistr = [animalz objectAtIndex:selectedani];
[self rearrange:anistr];
animalz is an array of NSString objects, but when you call [animalz objectAtIndex:selectedani], you assign the result to an int.
First of all, did you assigned selectedani before you used it? If not then you shouldn't use selectedani. It maybe the memory location or some other property of the button which may vary.
[animalz objectAtIndex:selectedani]
is returned an object, casting this object to an int not what you want and of course it's not an index too.
What can you do? Assign a tag number to the corresponding button dynamically, like
button.tag = 1;//or something like it
Then in the IBAction method retrieve the tag and use it to parse your array.
- (IBAction)buttonPressed:(id)sender
{
UIButton *pressedBtn = (UIButtton *)sender;
NSString *anistr = [animalz objectAtIndex:pressedBtn.tag];
//do what you want to do with the string
[self rearrange:anistr];
}
In this case, declare animalz as an iVar or property.

Resources