xcode array access with IBOutletCollections. Mind-boggled. - xcode

I have 2 arrays. One is a collection of buttons. The other one should be an array of dictionaries. I am logging the length/size/count of object in the arrays in the console using [arrayListName count]:
2012-07-19 19:56:59.001 ABC[3224:707] lastest_badge_outlet_collection count: 4
2012-07-19 19:56:59.007 ABC[3224:707] badges_array count: 1
ok so when running this loop I want to populate the images with the key value 'name' from each of the dictionaries in existence in the array (that is badges_array). At the moment I have dictionary stored in that array (which is fine). However when I run this through the loop it always populates the third image along
for(int i = 0; i < [lastest_badge_outlet_collection count]; i++){
UIButton *button = [lastest_badge_outlet_collection objectAtIndex:i];
if(i < [badges_array count]){
NSDictionary *badge_d = [badges_array objectAtIndex:i];
NSString *badge_d_image_string = [badge_d objectForKey:#"image"];
UIImage *badge_d_image = [UIImage imageNamed: badge_d_image_string];
[[button imageView] setImage:badge_d_image];
[[button imageView] setContentMode: UIViewContentModeScaleAspectFit];
[button setAlpha:1.0f];
} else {
[button setAlpha:0.5f];
}
}
Theoretically it should be populating the first image. Why is it doing this? How does it decide which order the items are in the outlet collection for example...
Mind boggled.
I tried rewiring them to the collection 1 by 1 by wiring them up in order with no success....
Here is a screenshot.
Thanks!

I don't think there is a way to predict the order of IBOutletCollection.
I guess what you need to do is sort the collection before use it.
You can set tag property for each button and sort them by those number.
Check this answer for more detail.

Related

NSMutableArray to NSDictionary and then add to an NSArray

My app stores images in an NSMutableArray. I then call those objects and then send them through email in the mailSender.parts section of the code below. The problem is it only adds the first objectatindex when I need to add all objects. I am confused on how to make each image in the self.arrSlidshowImg NSMutableArray add to the vcfPart2 NSDictionary and then add it as an array object so the mailSender.parts will send all images. Any thoughts? I should also note that I did an NSLog to see the results adding this code NSLog(#"VCF: %#", vcfPart2);. The log file showed each value in vcfPart2. So the code is calling each response.
NSDictionary *vcfPart2;
for (int i = 0; i < self.arrSlidshowImg.count; i++) {
NSData *vcfData = [self.arrSlidshowImg objectAtIndex:i];
vcfPart2 = [JFMailSender partWithType:PartTypeFilePart
Message:[vcfData base64EncodedStringWithOptions:0]
ContentType:#"image/jpeg"
ContentTransferEncoding:#"base64"
FileName:[NSString stringWithFormat:#"Individual_%d", i]];
}
mailSender.parts = [NSArray arrayWithObjects:plainPart2,vcfPart2,nil];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
[mailSender sendMail];
});
});
The following comes from a simple reading of your code, and among other things I have not looked up JFMailSender:
You declare a variable vcfPart2 to hold a reference to a dictionary
You enter a loop
In the loop you assign a value to vcfPart2, this value is presumably a reference to a dictionary as you report no warnings
Step 3 is executed self.arrSlidshowImg.count times, ice per iteration of the loop
You exit the loop, at this point vcfPart2 will hold the last reference assigned to it, the previous self.arrSlidshowImg.count - 1 having been overwritten
Your concern appears to be that when you then use vcfPart2 it only references one dictionary - but that is all it can ever do, that is it's type.
Maybe you intended to create a dictionary in your loop and then add that dictionary to a mutable array so that after the loop the array contains all the dictionaries?
HTH

Why does -[NSPasteboard readObjectsForClasses:options:] return only 1 item from a drag?

I'm writing a number of objects to NSPasteboard for a drag operation using beginDraggingSessionWithItems:event:source::
NSMutableArray *draggingItems = [NSMutableArray array];
for (NSUInteger i = 0; i < numItems; i++) {
NSPasteboardItem *pasteboardItem = [NSPasteboardItem new];
[pasteboardItem setDataProvider:[MyItem itemForIndex:i]
forTypes:#[#"com.test.FooType"]];
NSDraggingItem *draggingItem = [[NSDraggingItem alloc] initWithPasteboardWriter:pasteboardItem];
// ...
[draggingItems addObject:draggingItem];
}
[sourceView beginDraggingSessionWithItems:draggingItems
event:theEvent
source:self];
And in the dragging destination (in the same app), I try to receive these items using readObjectsForClasses:options:, but I only receive one of them.
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender
{
// sender.draggingPasteboard.pasteboardItems contains all items
NSArray *myItems = [sender.draggingPasteboard readObjectsForClasses:#[[MyItem class]] options:nil];
// pasteboard:item:provideDataForType: is called for each object on the pasteboard...
// ...but this method only returns 1 object (the first one)??
(Note that if you pass #[[NSPasteboardItem class]] for the classes, you get all items back unmodified.)
Any idea why this would this happen? Sample project available here (with lots of NSLogs to see that the items are actually being written to the pasteboard).
Turns out the implementation of -pasteboard:item:provideDataForType: needs to set data on the item, not on the pasteboard — doing the latter overwrites previously written data for other items.

Add values to NSTableview in a way that lets me reorder them at will

I have an NSTableView and need to add values. I was thinking of doing it with a NSArrayController, but near my table there are four buttons: Move to top, Move up, Move down, Move to bottom. I must be able to reorder the entries in the table with these buttons.
The only thing I can think of is to use an array of dictionaries, where the first entry of the dictionary is the value displayed and the second entry of the dictionary is a double that is used to sort the array. If I move a value up or down, I take the sort value of the entry before and after the destination sum them, and then I divide by two.
I am not sure that the solution I was thinking of is appropriate. What would be the best approach to this scenario?
------EDIT-----
Working on it, and now I am having difficulties writing the updated "order" value into the arraycontroller. Beside that i am having trouble in actually sorting the table with the "order" column once that the value has been updated. Here is my code:
-(IBAction)singleMoveKeywordUp:(id)sender
{
NSInteger selectedRow = [singleKeywordTable selectedRow];
double firstnum;
double secondnum;
double newnum;
NSMutableDictionary *kwmutabledict = [[NSMutableDictionary alloc] init];
if (selectedRow < 2)
{
firstnum = 0;
kwmutabledict = [keywordscontroller.arrangedObjects objectAtIndex:0];
secondnum = [[kwmutabledict valueForKey:#"order"] doubleValue];
}
else
{
kwmutabledict = [keywordscontroller.arrangedObjects objectAtIndex:selectedRow-2];
firstnum = [[kwmutabledict valueForKey:#"order"] doubleValue];
kwmutabledict = [keywordscontroller.arrangedObjects objectAtIndex:selectedRow-1];
secondnum = [[kwmutabledict valueForKey:#"order"] doubleValue];
}
NSMutableDictionary *newkwmutabledict = [[NSMutableDictionary alloc] init];
newnum = (firstnum + secondnum)/2;
[newkwmutabledict setObject:[NSString stringWithFormat:#"%#",[kwmutabledict valueForKey:#"keyword"]] forKey: #"keyword"];
[newkwmutabledict setObject:[NSString stringWithFormat:#"%f",newnum] forKey: #"order"];
[keywordscontroller.arrangedObjects replaceObjectAtIndex:selectedRow withObject:newkwmutabledict] ; //<--------
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:#"order" ascending:YES];
[singleKeywordTable setSortDescriptors:[NSArray arrayWithObject:sort]];
}
This is failing at the row marked with an Arrow with the error message -[_NSControllerArrayProxy replaceObjectAtIndex:withObject:]: unrecognized selector sent to instance 0x100450520
I can't figure out whats wrong.
keywordscontroller.arrangedObjects returns (NSArray *) which is NOT mutable, and NSArray does not contain selector "replaceObjectAtIndex:withObject:". Hence the exception/error "unrecognized selector".

Creating array of quiz questions that do not repeat

I'm trying to create a basic quiz app where the questions will not repeat. I've looked at several examples and believe I should be storing the questions in an array and then removing one from the array each time its used. I've tried the following code.
- (void)viewDidLoad
{
//The array of questions
NSMutableArray *questionArray = [[NSMutableArray alloc] initWithObjects:
[NSMutableArray arrayWithObjects:#"First Question",#"Answer A", nil],
[NSMutableArray arrayWithObjects:#"Second Quesiton",#"AnswerA",#"AnswerB", nil],
nil];
//remove used question from array
for (int i = questionArray.count; i>=0; --i) {
_questions = [questionArray objectAtIndex:arc4random() % questionArray.count];
[questionArray exchangeObjectAtIndex:i withObjectAtIndex:_questions];
}
//use array object
self.lblQuestion.text = [_questions objectAtIndex:0];
[self.btnA setTitle:[_questions objectAtIndex:1] forState:UIControlStateNormal];
[super viewDidLoad];
}
I'm getting the following warning:
Incompatible pointer to integer conversion sending NSMutableArray*_strong to parameter of type 'NSUInteger'
I take it this means I shouldn't be using another array to store the random question as I can't use this to remove the question from the array. However I don't know how else to do this?
Am I completely misunderstanding how I should go about this?
Since your goal here is to get non-repeating questions...
I believe that instead of removing the question you have already used, you should SHUFFLE your array at the beginning and then loop through the array one index at a time using a simple counter.
I hope you can find this piece of code helpful -- give it a shot:
-(NSMutableArray *)shuffleArray:(NSMutableArray *)anArray
NSUInteger count = [anArray count];
for (NSUInteger i = 0; i < count; ++i)
{
int nElements = count - i;
int n = (arc4random() % nElements) + i;
[anArray exchangeObjectAtIndex:i withObjectAtIndex:n];
}
return anArray;
}
-(void)viewDidLoad
{
//The array of questions
NSMutableArray *questionArray = [[NSMutableArray alloc] initWithObjects:
[NSMutableArray arrayWithObjects:#"First Question",#"Answer A", nil],
[NSMutableArray arrayWithObjects:#"Second Quesiton",#"AnswerA",#"AnswerB", nil],
nil];
//Shuffle the question array -- Now all indexes are shuffled and Random
questionArray = [self shuffleArray:questionArray];
//Every time you want to move to the next question, all you have to do is connect a button to the nextIndex action and let it do all the work!
//Use the nextIndex method to initialise -- we call it manually the first time so things would get going and something is displayed -- you can remove the line below if you want it to initialise on first button click! Your call the shots sir!
[self nextIndex];
[super viewDidLoad];
}
//Edit -- This method shows how to change question array index using a method
int currentIndex = 0;
-(IBAction)nextIndex
{
if ( currentIndex == [questionArray count] )
{
currentIndex = 0; //Resets the var when getting to the final Index
//The above line will result in a question loop -- meaning if you arrive at the last question, the next question will be the first! Pacman mode!
//If you want to stop at the last question just change the above line to return; and you're all set!
}
//Set _questions object to the current Index Array element
_questions = [questionArray objectAtIndex:currentIndex];
//Increment currentIndex for next use
currentIndex++;
//use the array object to set your objects' values
self.lblQuestion.text = [_questions objectAtIndex:0];
[self.btnA setTitle:[_questions objectAtIndex:1] forState:UIControlStateNormal];
}
You will end up having totally different questions that are shuffled every time.
I hope you find this helpful.

Pre-Select UIPickerView based on previous string in Xcode

I have the following code that populates a UIPickerView with the string value that was previously selected stored in the variable "preValue."
NSUInteger currentIndex = [arrayColour indexOfObject:preValue];
[ColourAndShadePicker selectRow:currentIndex inComponent:0 animated:YES];
The problem is that it doesn't seem to be matching the value exactly when there are spaces involved.
For instance if the 3 options are
Red
Green 1
Green 2
and the user selects Green 2, the Green 2 value is stored but on re-populate it's selecting Green 1 and not Green 2.
I think it has something to do with the spaces, and picking the first similar option?
Any ideas how to solve?
I'm unable to use the row number and need to match the string exactly.
EDIT:
To populate the array in the first place I'm using the following:
arrayColour = [[NSMutableArray alloc] init];
for (int i = 0; i < [substrings count]; i++)
{
//parse out each option (i)
NSString* companyoption = [substrings objectAtIndex:i];
//add as option to component
[arrayColour addObject:companyoption];
}
Thanks!

Resources