I created a emoji menu where users can choose them and use on top of pictures. However, it has been quite hard to get the "recently chosen emoji" part working properly because NSUserDefaults probably. When I choose an emoji in any of the 8 views, this emoji is added to an NSMutableArray, and the next time I open the emoji menu, this emoji is the first to appear in the "recently chosen emoji" view, as expected. I implemented the following code so that when I choose an emoji (be it directly through the "recently chosen emoji view" or just through any of the 8 other views - the 9 views are connected through a horizontal scroll view - if this emoji is already present at the "recently chosen emoji view", it is deleted from the view and added to the beginning of the view). Actually, I delete from the index in the emoji array, remove all subviews from the "recently chosen emoji" view and repopulate it with subviews according to the new emoji array:
- (void)emojiButtonPressed:(UIButton *)button {
NSLog(#"ARRAY EQUALS = %#", historicEmojiQueue);
NSLog(#"ARRAY AMOUNT EQUALS = %lu", (unsigned long)[historicEmojiQueue count]);
if ([historicEmojiQueue count] < 30){
NSLog(#"Not full");
for ( int j = 0; j < [historicEmojiQueue count]; j++){
NSLog(#"IN THE LOOP - START PRINT");
NSLog(#"%#", button.titleLabel.text);
NSLog(#"%#", historicEmojiQueue[j]);
NSLog(#"IN THE LOOP - END PRINT");
if ( button.titleLabel.text == historicEmojiQueue[j] ){
NSLog(#"EQUAL ADDITION TO ITEM ALREADY PRESENT");
[historicEmojiQueue removeObjectAtIndex:j];
}
}
[historicEmojiQueue insertObject:button.titleLabel.text atIndex:0];
}
else{
NSLog(#"Full");
BOOL equal = NO;
for ( int j = 0; j < [historicEmojiQueue count]; j++){
NSLog(#"IN THE LOOP - START PRINT");
NSLog(#"%#", button.titleLabel.text);
NSLog(#"%#", historicEmojiQueue[j]);
NSLog(#"IN THE LOOP - END PRINT");
if ( button.titleLabel.text == historicEmojiQueue[j] ){
NSLog(#"EQUAL ADDITION TO ITEM ALREADY PRESENT");
[historicEmojiQueue removeObjectAtIndex:j];
equal = YES;
}
}
if (equal == NO){
[historicEmojiQueue removeLastObject];
}
[historicEmojiQueue insertObject:button.titleLabel.text atIndex:0];
}
NSLog(#"ARRAY EQUALS aF= %#", historicEmojiQueue);
NSLog(#"ARRAY AMOUNT EQUALS aF= %lu", (unsigned long)[historicEmojiQueue count]);
[[NSUserDefaults standardUserDefaults] setObject:historicEmojiQueue forKey:#"historicQueue"];
[[NSUserDefaults standardUserDefaults] synchronize];
(MORE CODE THAT DOES NOT AFFECT THE PROBLEM)
}
When I choose an emoji, lets say Pizza, then choose another 5 emoji that are different, and choose Pizza again, it works perfectly: Pizza is removed from the sixth position and added to the first.
If I run the app again, my last changes are saved to NSUserDefaults, so Pizza will be the first emoji to display on the "recently chosen emoji" view. Now, if I choose Pizza again, the old Pizza and first on the list is not removed, and the new one is added, then having two Pizza emoji on the first and second position of the array, and then, in the view.
If I tap on any of the old emojis in the view ( like the second pizza), it is removed and added to the beginning. In the case of the Pizza, tapping on the old Pizza (second position) will not produce any visible changes since they are equal, but I am sure they exchange places. Here is the code in ViewDidLoad to get the array from NSUserDefaults:
NSMutableArray * historicEmojiQueue;
#implementation myEmojiView
-(instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
NSMutableArray * permanentQueue = [[NSUserDefaults standardUserDefaults] objectForKey: #"historicQueue"];
if ( permanentQueue == NULL) {
historicEmojiQueue = [[NSMutableArray alloc] init];
[[NSUserDefaults standardUserDefaults] setObject:historicEmojiQueue forKey:#"historicQueue"];
}
else{
historicEmojiQueue = [[NSMutableArray alloc] initWithArray:permanentQueue copyItems:YES];
}
}
(MORE CODE)
}
The reason of my question is the result of the print of the first block of code:
ARRAY EQUALS = (
"\Ud83c\Udf55",
"\Ud83c\Udf4e",
"\Ud83c\Udf4e",
"\Ud83c\Udf4e",
"\Ud83c\Udf52",
"\Ud83d\Ude18",
"\Ud83d\Ude43",
"\Ud83c\Udfc8",
"\Ud83c\Udf4e",
"\Ud83c\Udf4e",
"\Ud83d\Ude44",
"\Ud83d\Ude0e",
"\Ud83e\Udd14",
"\Ud83d\Ude12",
"\Ud83d\Ude07",
"\Ud83d\Ude1c",
"\Ud83e\Udd11",
"\Ud83d\Ude17",
"\Ud83d\Ude18",
"\Ud83c\Udf55",
"\Ud83c\Udf2d",
"\Ud83c\Udf56",
"\Ud83c\Udf4f",
"\Ud83c\Udf50",
"\Ud83c\Udf4b",
"\Ud83c\Udf4a",
"\Ud83d\Udc2f",
"\Ud83c\Udf46",
"\Ud83d\Udc3d",
"\Ud83d\Ude4a"
)
ARRAY AMOUNT EQUALS = 30
Full
IN THE LOOP - START PRINT
🍕
🍕
IN THE LOOP - END PRINT
IN THE LOOP - START PRINT
🍕
🍎
IN THE LOOP - END PRINT
.... ( LOTS OF OTHER PRINT STATEMENTS INSIDE LOOP)
ARRAY EQUALS aF= (
"\Ud83c\Udf55",
"\Ud83c\Udf55",
"\Ud83c\Udf4e",
"\Ud83c\Udf4e",
"\Ud83c\Udf4e",
"\Ud83c\Udf52",
"\Ud83d\Ude18",
"\Ud83d\Ude43",
"\Ud83c\Udfc8",
"\Ud83c\Udf4e",
"\Ud83c\Udf4e",
"\Ud83d\Ude44",
"\Ud83d\Ude0e",
"\Ud83e\Udd14",
"\Ud83d\Ude12",
"\Ud83d\Ude07",
"\Ud83d\Ude1c",
"\Ud83e\Udd11",
"\Ud83d\Ude17",
"\Ud83d\Ude18",
"\Ud83c\Udf55",
"\Ud83c\Udf2d",
"\Ud83c\Udf56",
"\Ud83c\Udf4f",
"\Ud83c\Udf50",
"\Ud83c\Udf4b",
"\Ud83c\Udf4a",
"\Ud83d\Udc2f",
"\Ud83c\Udf46",
"\Ud83d\Udc3d"
)
ARRAY AMOUNT EQUALS aF= 30
As you can see, even though the first emoji is exactly equal to the second both printed and in their unicode strings, they do not pass the check of whether they are equal as if they had different string representations. Since when I do not run the application again from Xcode and choose two equal emojis they do pass the check and print "EQUAL ADDITION TO ITEM ALREADY PRESENT", I am sure the problem relates to data being retrieved from NSUserDefaults, even though when I print the array I got from NSUserDefaults, it is exactly the same. I've tried multiple things when copying array from NSUserDefaults like [[NSMutableArray alloc] initWithArray:permanentQueue copyItems:YES]; and even looping through the NSUserDefaults array copying each item but nothing seems to solve the problem. Please help! :(
Where you are comparing strings at
if ( button.titleLabel.text == historicEmojiQueue[j] )
you should be using
if ( [button.titleLabel.text isEqualToString:historicEmojiQueue[j]] )
The first compares whether they occupy the same memory, the second whether they match.
Related
I am working on a project where I am adding objects to an array when the user taps the object in my UITableView. The user can add multiples of a single object, but no more than 4. I can't figure out how to stop the object from being added if there are already 4 in the array. Is there a way to check how many of a single object are stored in the array?
Here's what I have so far:
if (![deckArray containsObject:[cardArray objectAtIndex: indexPath.row]] || [deckArray containsObject:[cardArray objectAtIndex: indexPath.row]] ) {
[deckArray addObject:[cardArray objectAtIndex: indexPath.row]];
}
First, your conditional statement is always true. It says: "if the deck does or does not contain the object then add it."
Here is an inefficient way to do this is. It is slow because you need to enumerate every card in the deckArray, but if that array will never be very large (say 100 elements), then this is good enough:
id card = [cardArray objectAtIndex:indexPath.row];
int count = 0;
for( id deckCard in deckArray )
{
if( [deckCard isEqualTo:card] )
count++;
}
if( count < 4 )
[deckArray addObject:card];
If the order of deckArray does not matter, you could use NSCountedSet and have a very quick way to check how many times you've added the card:
// somewhere else, deck is declared as:
NSCountedSet * deck = [NSCountedSet set];
// somewhere else
id card = [cardArray objectAtIndex:indexPath.row];
if( [deck countForObject:card] < 4 )
[deck addObject:card];
I am using buttons and I assigned tag 0 to 10 . Then I made an action to get the clicked button's tag, and now I want to display the tag in a label . Also I have a cancel button C. If user wants to delete any number, he can click C button that I want to remove number from the label .
This is my screenshot to touch the number
- (void)viewDidLoad {
[super viewDidLoad];
self.title = #"Ezywire";
addnum=[[NSMutableArray alloc]init];
numbber=[[NSString alloc]init];
}
- (IBAction)NumberAction:(id)sender {
NSInteger tagvalue = [sender tag];
NSString *current=[NSString stringWithFormat:#"%ld", (long)tagvalue];
[addnum addObject:current];
NSString *temp;
for ( int i=0; i<[addnum count]; i++) {
numbber=[numbber stringByAppendingString:[addnum objectAtIndex:i]];
}
NSLog(#"data===%#",numbber);
ValueLable.text= numbber;
}
But in the label I am getting repeated number like this. How to implement this.
For example if user enters 2 then in the label
2
then he enters 7 then in the label
27
then he entered 9 then in the label
279
........ like this .
If user clicks C, then it remove from label last value is (last value removed)
27
The problem in your code is that numbber is initialized when the view is loaded, and never gets cleared again. However, each time a button is pressed, the whole addnum of digits gets appended to num again, creating repeated digits.
Fix this by removing num as an instance variable, making it a local to NumberAction: method, and setting it to an empty string every time the number is pressed.
Since you are planning to support the clearing action as well, you should make a private method that combines the digits from addnum array into a string. This way your NumberAction: and ClearAction would share the code that formats the array and sets the label. Your NumberAction: method would append a number and call FormatAndSetLabel, while the ClearAction method would remove the last digit if it is available, and call FormatAndSetLabel as well:
- (IBAction)NumberAction:(id)sender {
NSInteger tagvalue = [sender tag];
NSString *current=[NSString stringWithFormat:#"%ld", (long)tagvalue];
[addnum addObject:current];
[self FormatAndSetLabel];
}
- (IBAction)ClearAction:(id)sender {
if (!addnum.count) return;
[addnum removeLastObject];
[self FormatAndSetLabel];
}
-(void)FormatAndSetLabel {
NSMutableString *temp = [NSMutableString string];
for ( int i=0; i<[addnum count]; i++) {
[temp appendString:addnum[i]];
}
ValueLable.text= temp;
}
Also it might be interesting for you to have a look at Paul's Hegarty Stanford iOS development course (iPad and iPhone Application Development, Fall 2011)
https://itunes.apple.com/ru/itunes-u/ipad-iphone-application-development/id473757255?mt=10
Calculator app is used here as an example. Must see for the beginners.
I have a dynamic settings page. It depends on user's scenario, the settings page contents will be varied. I need prompt notice if user modified any setting text field or switcher value. Which way is more efficiency to verify multiple text field strings in customized settings view?
I have two ideas:
1, Traversal all subviews, if subview is textField or switcher, add these strings or boolean values into one NSDictionary obj, and use hash method get the dictionary object hash value and store it. When other event happen, do it again and compare the two hash value. If different, it means some setting is modified.
2, Traversal all subviews, save them into NSDictionary. When other event happen, it will traversal all subviews and compare every text field or switcher value separately. If any comparison found different, it means the settings page has unsaved setting.
Is there any other intelligent way to achieve this goal?
How about adding a tag to each control, say from value 1 to 20 (if you have 20 settings). Store the initial value of each setting in a mutable array at the position of the tag value (so if tag is 12, store at position 12). Make a copy of this array, and when they adjust a control store the new value in this second array at the same position (using the tag value as before). Then when they click on save, just compare the values between the two arrays with a simple loop.
Hope this helps.
In my scenario, the settings page is still developing, and the objects in the view will be dynamically, depends on user authorities. For the security rasone, it is not good idea that copy settings to other variables. Some people might change a setting, then change the setting back after view other settings. If use a simple flag to indicating changes, the change backed settings will be verified as changed.
My final solution is use md5 hash to snapshot every settings' value, just take lowest 4 chars and xor all snapshots to get one long unsigned integer (NSUInteger) hash value. After view did appear, get this hash value as reference. When user want to save settings or pop to parent view, we do this hash again. Then compare with reference hash value.
MD5 Function
#import <CommonCrypto/CommonCrypto.h>
- (NSUInteger) md5:(NSString *) input
{
const char *cStr = [input UTF8String];
unsigned char digest[16];
CC_MD5( cStr, strlen(cStr), digest ); // This is the md5 call
NSUInteger output = [[NSNumber numberWithUnsignedChar:digest[0]] intValue];
NSUInteger i;
i = (0x00000000|digest[3])<<24;
i = i|(0x00000000|digest[2])<<16;
i = i|(0x00000000|digest[1])<<8;
i = i|(0x00000000|digest[0])<<0;
output =i;
return output;
}
Snapshot Settings
- (NSUInteger) hashSettings{
NSUInteger settingsHash = 0;
for (NSObject *obj in settingsScrollView.subviews){
if([obj isKindOfClass:[UITextField class]]){
UITextField *textField = (UITextField *)obj;
settingsHash = settingsHash ^ [self md5:textField.text];
}
if([obj isKindOfClass:[UISwitch class]]){
UISwitch *switcher = (UISwitch *)obj;
settingsHash = settingsHash ^ (switcher.isOn?switcher.hash:0xFFFFFFFF);
}
if([obj isKindOfClass:[UIButton class]]){
UIButton *button = (UIButton *)obj;
settingsHash = settingsHash ^ (button.isHidden?button.hash:0xFFFFFFFF);
}
}
NSLog(#"settings Hash : %#",[self getBitStringForInt:settingsHash]);
return settingsHash;
}
For NSLog easily
- (NSString *)getBitStringForInt:(NSUInteger)value {
NSString *bitsSting = #"";
for(int i = 0; i < 32; i ++) {
bitsSting = [NSString stringWithFormat:#"%i%#", value & (1 << i) ? 1 : 0, bitsSting];
}
return bitsSting;
}
Hello: I'm using a collection view within my app, and I've noticed that it's taking longer than expected to refresh using reloadData. My collection view has 1 section, and I'm testing it with 5 cells (each of which has 2 buttons and a label). I put some logs into my code to show how long the system is actually taking to refresh. Interestingly enough, the logs indicate that it's refreshing faster than it is. On a device, for example, it will take up to ~0.2sec (noticeable), but here are the logs:
0.007s From the time reloadData is called to the time cellForItemAtIndexPath is called the first time
0.002s Per cell to load and be returned
0.041s From the time reloadData is called to the time where cell #5 is returned
There isn't anything particularly intensive in the cellForItemAtIndexPath function (basically just finds a dictionary with 3 values within an NSArray at the indexPath's row). Even when I removed this and just returned a cell with a blank button, I saw the same behavior, however.
Does anyone have any idea as to why this may be happening? It's only happening on a physical device (iPad Air), by the way. Thanks!
EDIT #1
Per #brian-nickel's comment, I used the Time Profiler instrument, and found that it does indeed spike each time reloadData is called. Here's a screenshot:
#ArtSabintsev, here is the function surrounding the reloadData call, followed by the cellForItemAtIndexPath:
//Arrays were just reset, load new data into them
//Loop through each team
for (NSString *team in moveUnitsView.teamsDisplaying) { //CURRENT TEAM WILL COME FIRST
//Create an array for this team
NSMutableArray *teamArr = [NSMutableArray new];
//Loop through all units
for (int i = [Universal units]; i > 0; i--) {
//Set the unit type to a string
NSString *unitType = [Universal unitWithTag:i];
//Get counts depending on the team
if ([team isEqualToString:currentTeam.text]) {
//Get the number of units of this type so that it supports units on transports. If the territory is a sea territory and the current unit is a ground unit, check the units in the transports instead of normal units
int unitCount = (ter.isSeaTerritory && (i == 1 || i == 2 || i == 8)) ? [self sumOfUnitsInTransportsOfType:unitType onTerritory:ter onTeam:team] : [ter sumOfUnitsOfType:unitType onTeam:team];
//Get the number of movable units on this territory
int movableCount = 0;
if (queue.selectedTerr != nil && queue.selectedTerr != ter) { //This is here to prevent the user from selecting units on another territory while moving units from one territory
movableCount = 0;
} else if (ter.isSeaTerritory && (i == 1 || i == 2 || i == 8)) { //Units on transports - can be an enemy territory
movableCount = [self sumOfUnitsInTransportsOfType:unitType onTerritory:ter onTeam:team];
} else if ([Universal allianceExistsBetweenTeam:team andTeam:ter.currentOwner] || i == 3 || i == 9) { //Other units - only planes can be on an enemy territory
movableCount = [ter sumOfMovableUnitsOfType:unitType onTeam:team];
}
//See if there are units of this type on this territory on this team
if (unitCount > 0) {
//Add data to this team's dictionary
NSMutableDictionary *unitInfo = [NSMutableDictionary new];
[unitInfo setObject:#(i) forKey:#"UnitTag"];
[unitInfo setObject:unitType forKey:#"UnitType"];
[unitInfo setObject:#(unitCount) forKey:#"Count"];
[unitInfo setObject:#(movableCount) forKey:#"MovableCount"];
[unitInfo setObject:team forKey:#"Team"];
//Add the dictionary
[teamArr addObject:unitInfo];
//Increment the counter
if (unitsOnCT) { //Must check or it could cause a crash
*unitsOnCT += 1;
}
}
}
}
//Add the team array
[moveUnitsView.unitData addObject:teamArr];
}
//Reload the data in the collection view
[moveUnitsView.collectionV reloadData];
And my cellForItemAtIndexPath's relevant code:
//Dequeue a cell
UnitSelectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"UnitSelectionCell" forIndexPath:indexPath];
//Get the team array (at the index of the section), then the unit's data (at the index of the row)
NSMutableDictionary *unitData = (moveUnitsView.unitData[indexPath.section])[indexPath.row];
//Get values
int unitTag = [[unitData objectForKey:#"UnitTag"] intValue];
int count = [[unitData objectForKey:#"Count"] intValue];
int movableCount = [[unitData objectForKey:#"MovableCount"] intValue];
NSString *unitType = [unitData objectForKey:#"UnitType"];
//Set the cell's values
[cell.upB addTarget:self action:#selector(upMoveUnits:) forControlEvents:UIControlEventTouchUpInside]; [cell.upB setTag:unitTag];
[cell.iconB setBackgroundImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[Universal imageNameForUnit:unitType team:[unitData objectForKey:#"Team"]] ofType:nil]] forState:UIControlStateNormal];
[cell.iconB setTitle:[Universal strForExpDisplay:count] forState:UIControlStateNormal];
[Universal adjustTitlePlacementOfB:cell.iconB autosize:FALSE]; //Don't autosize because this is a collection view
cell.unitTypeL.text = unitType;
cell.unitTypeL.adjustsFontSizeToFitWidth = cell.unitTypeL.adjustsLetterSpacingToFitWidth = TRUE;
//Set fonts
[Universal setFontForSubviewsOfView:cell];
//Return the cell
return cell;
When the collection view is initialized, cells are registered using:
[moveUnitsView.collectionV registerNib:[UINib nibWithNibName:#"UnitSelectionCell" bundle:nil] forCellWithReuseIdentifier:#"UnitSelectionCell"];
EDIT #2
#roycable and #aaron-brager pointed out that this could be caused by using imageWithContentsOfFile:. To test this out, I changed cellForItemAtIndexPath to this:
//Dequeue a cell
UnitSelectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"UnitSelectionCell" forIndexPath:indexPath];
//Get the team array (at the index of the section), then the unit's data (at the index of the row)
NSMutableDictionary *unitData = (moveUnitsView.unitData[indexPath.section])[indexPath.row];
//Get values
int unitTag = [[unitData objectForKey:#"UnitTag"] intValue];
[cell setBackgroundColor:[UIColor redColor]];
[cell.upB removeTarget:nil action:NULL forControlEvents:UIControlEventTouchUpInside];
[cell.upB addTarget:self action:#selector(upMoveUnits:) forControlEvents:UIControlEventTouchUpInside]; [cell.upB setTag:unitTag];
//Return the cell
return cell;
Strangely, this doesn't seem to fix the issue. It's literally doing no intensive tasks in that function but it still seems to be lagging (and the Time Profiler seems to confirm that).
In response to the requests for code from Universal, instead of posting code I'll just summarize it:
+units just returns 17
+unitWithTag: uses a switch to return an NSString corresponding to a number between 1-17
+allianceExistsBetweenTeam: sees if an array contains one of the strings
+setFontForSubviewsOfView: is a recursive function that basically uses this code
Unfortunately, this doesn't seem very relevant since the issue is still occurring with the oversimplified cellForItemAtIndexPath function.
I also implemented #aaron-brager's new suggestions. I removed the target before adding a new one, and I made the changes to Time Profiler. I didn't see anything really pop out... Here's the screenshot. Everything related to UIImage is irrelevant to this question, as is NSKeyedArchiver, so the only other things that really make sense are strings, arrays, and dictionaries:
Any and all help is greatly appreciated - I really need to get this fixed (hence the bounty). Thank you!
Edit #3 - Solution identified
So, it turns out that the issue wasn't in either of those functions. The issue was the function (let's call it Function A) that called the update function above (let's call it Function B). Right after Function A called Function B, it performed a CPU-intensive task. I wasn't aware of the fact that reloadData is at least partially asynchronous, so I'm assuming the CPU-intensive task and reloadData ended up racing for CPU time. I solved my problem by adding the following right before return cell;:
if (indexPath.row == [self collectionView:collectionView numberOfItemsInSection:indexPath.section] - 1) {
[self performSelector:#selector(performMyCPUIntensiveTask:) withObject:myObject afterDelay:0.1];
}
I hope this helps someone else in the future. Thank you to everyone who helped, I sincerely appreciate it.
Make sure you're on the main thread when you call reloadData.
NSLog("on main thread: %#", [NSThread isMainThread] ? #"YES" : #"NO");
If you're not then use GCD to send the message on the main thread:
dispatch_async(dispatch_get_main_queue(), ^{
[moveUnitsView.collectionV reloadData];
});
(Not 100% sure about syntax, I just typed this into the browser)
Some possibilities:
Your presumably recursive function to set the fonts is probably expensive.
A few of the other Universal functions look like they might be expensive.
It does not appear that you ever remove the button target and every time a cell is reused, you are adding additional targets to it.
imageWithContentsOfFile: skips the cache; use imageNamed: instead.
so I'm creating a contact list app and I'm storing everything into an NSMutableArray. I've managed to get add function working perfectly. But I'm struggling with the Previous/Next functions.
I can get it to go back one object in the array when pressing previous, but i Can't get it to go back any further? here's my code: I have two extra classes, PhoneBookEntry which is a subclass of the Person class. These classes contain three strings, Firstname,lastname and studentID
- (IBAction)addPerson:(id)sender {
PhonebookEntry *person = [[PhonebookEntry alloc] init];
NSLog(#"%#",self.firstName.text);
person.firstName = self.firstName.text;
person.lastName = self.lastName.text;
person.phoneNumber = self.phoneNumber.text;
[self.entries addObject:person];
Here's my Previous button:
int length;
length = [self.entries count];
if (length > 0) {
int index;
index = [self.entries count] - 1;
NSLog (#"%d the index is", index);
NSLog(#"object %#", [self.entries objectAtIndex:index]);
} else {
NSLog (#"No contacts have been entered. No");
}
//NSLog(#"%d is the length - 1 hopefully", length);
//NSLog (#"index at %d is ", length);
I've tried removing the - 1 here:
index = [self.entries count] - 1;
and changing then on the next line putting index--; but nothing seems to work. it just goes back once.
I understand that length is getting the amount of objects in the index, and then -1 but shouldnt i-- at the end of the count / - 1 keep removing it everytime its pressed??
Any ideas? Cheers
You're going to keep hitting the same index with that piece of code - you need to store the state somewhere. Who is going to hold onto what the current index is? With a good designed system the model should really take care of this.
You are best off storing the current index into an ivar and updating that every time the button is pressed.
#interface OKAClass ()
#property (nonatomic, assign) NSInteger currentIndex;
#end
//... initialise the property with a default value
self.currentIndex = [self.entries count] - 1;
//... when the button is pressed decrement the index (you might want some min / max validation or use modulus to loop over and start from the top again)
NSLog(#"%#", self.entries[self.currentIndex--]);