One UIPickerView Two Data Sources/Views works once then crashes - iphone

I am trying to display a single UIPickerView in my app and depending on what button is selected a UIPickView will popup and populate with the relevant data for the button selected. No sure if it matters but one UIPickerView has three columns and one has two. I can get both of them to work perfectly when the are separate but the minute that I nest them into if statements it breaks.
On the third time when I select the button that fires the opposite UIPickerView it crashes and give me the error of NSRangeException and that it is trying to find the object at index 2 in an array [0...1]. My understanding is that the program thinks that there is an object in a spot in the array that doesn't exist.
I have tried the [picker reloadAllComponents] method and have it called each time the button is selected but as stated above that only works once and then it quits. The strange thing is that if I select the button that I pressed for the second set of code it works perfectly. It is when I select a button that would make the UIPickerView have to change its view that it crashes.
I am really new to iOS development and Objective C and hope that someone out there knows what I am doing wrong. I will post any code that you guys need and will post a couple samples just to understand what is going on.
Here is one of the buttons methods that sets an int to 2 and also calls the method to show the picker.
-(IBAction)linePopupPicker{
picker = 2;
[self pickerShow];
}
This code is the other method which is pretty much the same as the other (I am aware that I haven't implemented the UserDefaults into the second button yet)
-(IBAction)namePicker{
field = 1;
picker = 1;
NSLog(#"The value of field is:%i", field);
NSUserDefaults *pickerViewSelectionDefaults = [NSUserDefaults standardUserDefaults];
[tipPicker selectRow:[pickerViewSelectionDefaults integerForKey:#"pickerViewSelectionKey"] inComponent:0 animated:NO];
[tipPicker selectRow:[pickerViewSelectionDefaults integerForKey:#"pickerViewNameColor"] inComponent:1 animated:NO];
[tipPicker selectRow:[pickerViewSelectionDefaults integerForKey:#"pickerViewNameFontSize"] inComponent:2 animated:NO];
[self pickerShow];
}
This is the method that calls the UIPickerView. I have it so that it emerges onto the view rather than being static. I thought that this would be the best place to reload the components.
-(IBAction)pickerShow{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
CGAffineTransform transform = CGAffineTransformMakeTranslation(0, 240);
pickerView.transform = transform;
[self.view addSubview:pickerView];
[tipPicker reloadAllComponents];
[UIView commitAnimations];
}
Finally here is just a sample of the code that is used throughout the various methods that need to be called for the UIPickerView.
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
if (picker ==2) {
switch (component)
{
case 0:
{
UILabel *lineColorLabel = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 130, 44)] autorelease];
lineColorLabel.backgroundColor = [UIColor clearColor];
NSString *lineTempColor = [colorArray1 objectAtIndex:row];
//NSLog(#"The String Color Name:%#", tempColor);
UIColor *myColor1 = [UIColor performSelector:NSSelectorFromString(lineTempColor)];
lineColorLabel.backgroundColor = myColor1;
return lineColorLabel;
}
case 1:
{
UILabel *alphaLabel = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0,40, 44)] autorelease];
alphaLabel.text = [alphaArray objectAtIndex:row];
alphaLabel.font = [UIFont systemFontOfSize:18];
alphaLabel.textAlignment = UITextAlignmentCenter;
alphaLabel.backgroundColor = [UIColor clearColor];
alphaLabel.shadowColor = [UIColor whiteColor];
return alphaLabel;
}
default:
break;
}
}
else if (picker == 1)
{
switch (component)
{
case 0:
{
UILabel *fontLabel = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 130, 44)] autorelease];
fontLabel.backgroundColor = [UIColor clearColor];
fontLabel.shadowColor = [UIColor whiteColor];
fontLabel.text = [fontNames objectAtIndex:row];
NSString *font = [fontNames objectAtIndex:row];
fontLabel.font = [UIFont fontWithName:font size:18.0];
fontLabel.textAlignment = UITextAlignmentLeft;
return fontLabel;
}
case 1:
{
UILabel *colorLabel = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 35, 44)] autorelease];
NSString *tempColor = [colorArray objectAtIndex:row];
//NSLog(#"The String Color Name:%#", tempColor);
UIColor *myColor = [UIColor performSelector:NSSelectorFromString(tempColor)];
colorLabel.backgroundColor = myColor;
return colorLabel;
}
case 2:
{
UILabel *sizeLabel = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0,40, 44)] autorelease];
sizeLabel.text = [fontSizeArray objectAtIndex:row];
sizeLabel.font = [UIFont systemFontOfSize:18];
sizeLabel.textAlignment = UITextAlignmentCenter;
sizeLabel.backgroundColor = [UIColor clearColor];
sizeLabel.shadowColor = [UIColor whiteColor];
return sizeLabel;
}
default:
break;
}
}
return 0;
}
Here are the data methods:
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView {
if (picker == 2) {
return 2;
}else if (picker == 1) {
return 3;
}
//return 3;
}
- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component { // This method also needs to be used. This asks how many rows the UIPickerView will have.
if (picker == 2) {
if (component == 0) {
return [colorArray1 count];
}
return [alphaArray count];
}else if (picker == 1) {
if (component == 0) {
return [fontNames count];
}else if (component == 1) {
return [colorArray count];
}
return [fontSizeArray count];
}
}
I hope this post provides all of the information that is need to help me get this fixed. I really appreciate it and hope that I am just missing something really simple. Thank you in advanced.
I am really new to iOS development and Objective C so this problem is really stumping me.

case 1 in the if ( picker == 2) switch statement has an opening brace but no closing one.
EDIT
- (void) savePickerOne {
[pickerViewSelectionDefaults setInteger:[tipPicker selectedRowInComponent:0] ForKey:#"pickerViewSelectionKey"];
[pickerViewSelectionDefaults setInteger:[tipPicker selectedRowInComponent:1] ForKey:#"pickerViewNameColor"];
[pickerViewSelectionDefaults setInteger:[tipPicker selectedRowInComponent:2] ForKey:#"pickerViewNameFontSize"];
}

Related

UISegmentedControl not updating view

I am building an app in Xcode 5, and I ran into some strange behavior of UISegmentedControl.
first some info on the app i'm building:
I'm building an app in which I want to allow users to order products at registered companies. As an extra service, I want to allow them to see the orders they did, and even to filter the orders on their status: All orders, Active orders & Delivered orders. the orders are displayed in a UITableView, and I created a UISegmentedControl inside the header view to filter the orders. when the selectedSegmentIndex of that UISegmentedControl changes, it executes an NSPredicate to filter the array and display only the desired orders.
now it's working all fine, except for 1 thing: The UISegmentedControl I have does not update it's view when I select another segment. It's default selectedSegmentIndex is 'Active', because users are probably most interested in the active orders, but when I change it to 'All', the tableview displays all orders (so the predicate is working), but the view remains on the same selectedSegmentIndex.
I did a lot of research to solve this but no answer solves my problem.. my code:
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
if(section == 0) {
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0.0f,0.0f, 320, 45)]; // x,y,width,height
//label
UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320, 20)];
title.text = #"Kies een filter...";
[headerView addSubview:title];
//segmentedcontrol
NSArray *itemArray = [NSArray arrayWithObjects: #"Alle", #"Actief", #"Afgehandeld", nil];
control = [[UISegmentedControl alloc] initWithItems:itemArray];
[control setFrame:CGRectMake(0.0f, 20.0f, 320.0, 35.0)];
control.userInteractionEnabled = YES;
control.tintColor = [UIColor blackColor];
[control setEnabled:YES];
[control addTarget:self action:#selector(changeFilter:) forControlEvents:UIControlEventAllEvents];
[headerView addSubview:control];
//label containing selected filter info
UILabel *info = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 55.0f, 320, 20)];
if ([selectedFilterInfo isEqualToString:#"Alle"]) {
info.text = #"Alle orders:";
}
else if ([selectedFilterInfo isEqualToString:#"Actief"]) {
info.text = #"Alle actieve orders:";
}
else if ([selectedFilterInfo isEqualToString:#"Afgehandeld"]) {
info.text = #"Alle afgehandelde orders:";
}
[headerView addSubview:info];
headerView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"bar.png"]];
return headerView;
}
}
and the action it triggers:
- (void)changeFilter:(id)sender {
UISegmentedControl *segmentedControl = (UISegmentedControl *)sender;
if (segmentedControl.selectedSegmentIndex == 0) {
selectedFilterInfo = #"Alle";
filteredArray = nil;
[segmentedControl reloadInputViews];
[segmentedControl setSelectedSegmentIndex:0];
}
else if (segmentedControl.selectedSegmentIndex == 1) {
NSPredicate *deliveredpredicate = [NSPredicate predicateWithFormat:#"SELF.delivered contains[c] %#", #"0"];
NSMutableArray *notDeliveredArray = [NSMutableArray arrayWithArray:[sortedArray filteredArrayUsingPredicate:deliveredpredicate]];
filteredArray = [NSMutableArray arrayWithArray:notDeliveredArray];
selectedFilterInfo = #"Actief";
[segmentedControl reloadInputViews];
[segmentedControl setSelectedSegmentIndex:1];
}
else if (segmentedControl.selectedSegmentIndex == 2) {
NSPredicate *deliveredpredicate = [NSPredicate predicateWithFormat:#"SELF.delivered contains[c] %#", #"1"];
NSArray *deliveredArray = [sortedArray filteredArrayUsingPredicate:deliveredpredicate];
filteredArray = [NSMutableArray arrayWithArray:deliveredArray];
selectedFilterInfo = #"Afgehandeld";
[segmentedControl reloadInputViews];
[segmentedControl setSelectedSegmentIndex:2];
}
[self.tableView reloadData];
}
I did not include the numberOfCellsInSection etcetera because the tableview part is working perfectly. the only thing that's not working is updating the view.
Any solution would be really appreciated, Thank you all in advance!!
reloadData will reload the tableView, and when you reload the tableView all headerViews will be reloaded too. When the tableView was reloaded there is a new header. And the UISegmentedControl you see now is not the one that you have tapped.
Create an ivar that holds your selected index
#implementation .. {
NSInteger selectedIndex;
}
when creating the view restore the saved index
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
/* ... */
control = [[UISegmentedControl alloc] initWithItems:itemArray];
control.selectedSegmentIndex = selectedIndex;
/* ... */
}
save the index when changing the segmentedControl
- (void)changeFilter:(id)sender {
UISegmentedControl *segmentedControl = (UISegmentedControl *)sender;
selectedIndex = segmentedControl.selectedSegmentIndex;
if (segmentedControl.selectedSegmentIndex == 0) {
selectedFilterInfo = #"Alle";
filteredArray = nil;
}
/* ... */
// reloads the table and all header views!
[tableView reloadData];
}
And btw. when you use UISegmentedControls there is no need to call setSelectedSegmentIndex: on it again, the tap sets the index already. And reloadInputViews is totally useless for a UISegmentedControl. But I guess this code was just added because it didn't work. Don't forget to remove it ;-)

How to remove duplicated items in iCarousel

https://github.com/nicklockwood/iCarousel/issues/278
I am going to use the iCarousel to show the images linearly.
These images will be gotten dynamically.
Assume that there are 2 images.
But when I update iCarousel, there are also 2 images in background as following image.
While debugging code, I found that viewForItemAtIndex function is called 2 times after I called reloadData function.
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
So there are 4 images in iCarousel.
How to prevent to be called 2 times?
Please help me to fix this problem asap.
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
UIImageView *puzzlePhoto = nil;
UIImageView *puzzleBG = nil;
UILabel *label = nil;
if (view == nil)
{
view = [[UIImageView alloc] init];
view.frame = CGRectMake(0, 0, 128, 112);
view.backgroundColor = [UIColor clearColor];
view.layer.doubleSided = NO;
puzzlePhoto = [[UIImageView alloc] initWithFrame:CGRectMake(46, 48, 40, 40)];
//! get friend's photo
FForesight *foresightCurrent = (carousel == self.icGameOnwhoAREus) ? [controller.gameManager.m_arrayStartedForesights objectAtIndex:index] : [controller.gameManager.m_arrayEndedForesights objectAtIndex:index];
UIImage *imgPuzzle = [foresightCurrent getPuzzleImage];
if (imgPuzzle)
puzzlePhoto.image = imgPuzzle;
else
puzzlePhoto.image = [UIImage imageNamed:#"puzzle background_small.png"];
puzzleBG = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 128, 112)];
if (((foresightCurrent.m_intStage & FForesightStage_First) && !foresightCurrent.m_FCreatedByFriend) ||
((foresightCurrent.m_intStage & FForesightStage_Second) && foresightCurrent.m_FCreatedByFriend))
puzzleBG.image = [UIImage imageNamed:#"multi_game_one_item_bg_me.png"];
else
puzzleBG.image = [UIImage imageNamed:#"multi_game_one_item_bg.png"];
//! get friend name
FUser *userFriend = foresightCurrent.m_userFriend;
label = [[UILabel alloc] initWithFrame:CGRectMake(32, 32, 68, 16)];
label.text = userFriend.m_strName;
label.textAlignment = NSTextAlignmentCenter;
label.font = [UIFont boldSystemFontOfSize:10];
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor colorWithRed:205.0f/256 green:55.0f/256 blue:2.0f/255 alpha:1];
[view addSubview:puzzlePhoto];
[view addSubview:puzzleBG];
[view addSubview:label];
}
return view;
}
The problem is almost certainly due to the views being recycled incorrectly. Views are re-used with different indexes, you you should never set index-specific properties in your view creation code. Here is the correct way to set up your item view:
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
UIImageView *puzzlePhoto = nil;
UIImageView *puzzleBG = nil;
UILabel *label = nil;
const NSInteger puzzlePhotoTag = 1;
const NSInteger puzzleBGTag = 2;
const NSInteger labelTag = 3;
if (view == nil)
{
//*************************************************
//do setup that is the same for every item view here
//*************************************************
view = [[UIImageView alloc] init];
view.frame = CGRectMake(0, 0, 128, 112);
view.backgroundColor = [UIColor clearColor];
view.layer.doubleSided = NO;
puzzlePhoto = [[UIImageView alloc] initWithFrame:CGRectMake(46, 48, 40, 40)];
puzzlePhoto.tag = puzzlePhotoTag;
[view addSubview:puzzlePhoto];
puzzleBG = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 128, 112)];
puzzleBG.tag = puzzleBGTag;
[view addSubview:puzzleBG];
label = [[UILabel alloc] initWithFrame:CGRectMake(32, 32, 68, 16)];
label.textAlignment = NSTextAlignmentCenter;
label.font = [UIFont boldSystemFontOfSize:10];
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor colorWithRed:205.0f/256 green:55.0f/256 blue:2.0f/255 alpha:1];
label.tag = labelTag;
[view addSubview:label];
}
else
{
//get references to subviews
puzzlePhoto = (UIImageView *)[view viewWithTag:puzzlePhotoTag];
puzzleBG = (UIImageView *)[view viewWithTag:puzzleBGTag];
label = (UILabel *)[view viewWithTag:labelTag];
}
//*************************************************
//do setup that is different depending on index here
//*************************************************
//! get friend's photo
FForesight *foresightCurrent = (carousel == self.icGameOnwhoAREus) ? [controller.gameManager.m_arrayStartedForesights objectAtIndex:index] : [controller.gameManager.m_arrayEndedForesights objectAtIndex:index];
UIImage *imgPuzzle = [foresightCurrent getPuzzleImage];
if (imgPuzzle)
puzzlePhoto.image = imgPuzzle;
else
puzzlePhoto.image = [UIImage imageNamed:#"puzzle background_small.png"];
if (((foresightCurrent.m_intStage & FForesightStage_First) && !foresightCurrent.m_FCreatedByFriend) || ((foresightCurrent.m_intStage & FForesightStage_Second) && foresightCurrent.m_FCreatedByFriend))
puzzleBG.image = [UIImage imageNamed:#"multi_game_one_item_bg_me.png"];
else
puzzleBG.image = [UIImage imageNamed:#"multi_game_one_item_bg.png"];
//! get friend name
FUser *userFriend = foresightCurrent.m_userFriend;
label.text = userFriend.m_strName;
return view;
}
As for the scrolling inertia problem, if you're still seeing that after applying this fix, file a separate bug report on the github page.
I solved this problem by performing reloadData on mainThread
[carousel performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:YES];

Why is my multi-component UIPickerView crashing?

I'm trying to create a simple pickerview with two components, drawing its label data from a small mutablearray and output data from a simple matrix. The purpose of this wheel is to select a value from 0 to 1000, and then spit out the number in a label and the value to the rest of the application's functions.
Some specific info about what I'm doing: (skip down to the last paragraph for the problem)
The left wheel spins a "hundred's" column, and the right wheel spins a "ten's" column, so essentially you're creating one value from two wheels. All I want to do is let the user create a value of 0, 10, 20, 30... 990, 1000 (every ten units up to 1000).The first component is easy to label, but I have two arrays to populate the second component's row's labels. The first array for the second component creates the 00 - 90 label, the second array (for when 1000 is selected) just has a 00 value. So when the user wants to select 1000, the 10 is on the first wheel and 00 on the second. I change the row count for the second wheel component when the first wheel component is at row 10. So now the second component only shows "00". My didSelectRow method uses a matrix for values of 0 - 990 and works great. And I just make a string and convert it to a number for when the user selects 1000 using if statements.
The problem is in the rare circumstance of when the user spins Component 0 to create the value of "1000" (the last row), and if they were start spinning the second component before the first component has a chance to stop spinning (basically spinning in a hurry!), the app crashes. I think it's trying to find a value for a row that doesn't exist. I have other parts of my app that function similarly and they also crash under the same situation. Is there a problem with my approach to changing the number of rows/labels for rows based on the selection of a different component? Or is it something simple in my code?
Thanks for reading and thanks in advance for any help!
Here's the code:
//Baggage Array
baggageHundredsArray = [[NSMutableArray alloc] init];
for (int i = 1; i <= 10; i++) {
NSString *myBagString = [NSString stringWithFormat:#"%d", i];
[baggageHundredsArray addObject:myBagString];
}
[baggageHundredsArray insertObject:#"- " atIndex:0];
baggageTensArray = [[NSMutableArray alloc] init];
for (int i = 10; i <= 90; i = i + 10) {
NSString *myBagString2 = [NSString stringWithFormat:#"%d lbs.", i];
[baggageTensArray addObject:myBagString2];
}
[baggageTensArray insertObject:#"00 lbs." atIndex:0];
baggageTensArray2 = [[NSMutableArray alloc] init];
[baggageTensArray2 insertObject:#"00 lbs." atIndex:0];
- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component {
if (thePickerView == baggagePicker) {
NSInteger numComps2 = 0;
switch (component)
{
case 0:
numComps2 = [baggageHundredsArray count];
break;
case 1:
if ([baggagePicker selectedRowInComponent:0] <= 9)
{
numComps2 = [baggageTensArray count];
}
else
{
numComps2 = [baggageTensArray2 count];
}
break;
}
return numComps2;
}
}
- (UIView *)pickerView:(UIPickerView *)pickerView
viewForRow:(NSInteger)row
forComponent:(NSInteger)component
reusingView:(UIView *)view {
UILabel *pickerLabel = (UILabel *)view;
if (pickerView == baggagePicker) {
if ((pickerLabel == nil) || ([pickerLabel class] != [UILabel class])) { //newlabel
CGRect frame = CGRectMake(0.0, 0.0, 110, 32.0);
pickerLabel = [[[UILabel alloc] initWithFrame:frame] autorelease];
pickerLabel.textAlignment = UITextAlignmentLeft;
pickerLabel.backgroundColor = [UIColor clearColor];
pickerLabel.font = [UIFont boldSystemFontOfSize:12];
}
pickerLabel.textColor = [UIColor blackColor];
switch (component)
{
case 0:
//CGRect frame = CGRectMake(0.0, 0.0, 80, 32);
//pickerLabel = [[[UILabel alloc] initWithFrame:frame] autorelease];
[pickerLabel setTextAlignment:UITextAlignmentRight];
[pickerLabel setBackgroundColor:[UIColor clearColor]];
[pickerLabel setFont:[UIFont boldSystemFontOfSize:23]];
[pickerLabel setTextColor:[UIColor blackColor]];
[pickerLabel setText:[baggageHundredsArray objectAtIndex:row]];
break;
case 1:
if ([baggagePicker selectedRowInComponent:0] <= 9) {
[pickerLabel setTextAlignment:UITextAlignmentLeft];
[pickerLabel setBackgroundColor:[UIColor clearColor]];
[pickerLabel setFont:[UIFont boldSystemFontOfSize:21]];
[pickerLabel setTextColor:[UIColor blackColor]];
[pickerLabel setText:[baggageTensArray objectAtIndex:row]];
}
else
{
[pickerLabel setTextAlignment:UITextAlignmentLeft];
[pickerLabel setBackgroundColor:[UIColor clearColor]];
[pickerLabel setFont:[UIFont boldSystemFontOfSize:21]];
[pickerLabel setTextColor:[UIColor blackColor]];
[pickerLabel setText:[baggageTensArray2 objectAtIndex:row]];
}
break; }
return pickerLabel;
}
- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (thePickerView == baggagePicker) {
[baggagePicker reloadAllComponents];
NSInteger hundredsWheel = [thePickerView selectedRowInComponent:0];
NSInteger tensWheel = [thePickerView selectedRowInComponent:1];
//lbs.
int column5 [10][10] = {
{0,10,20,30,40,50,60,70,80,90},
{100,110,120,130,140,150,160,170,180,190},
{200,210,220,230,240,250,260,270,280,290},
{300,310,320,330,340,350,360,370,380,390},
{400,410,420,430,440,450,460,470,480,490},
{500,510,520,530,540,550,560,570,580,590},
{600,610,620,630,640,650,660,670,680,690},
{700,710,720,730,740,750,760,770,780,790},
{800,810,820,830,840,850,860,870,880,890},
{900,910,920,930,940,950,960,970,980,990},
};
// Totals Label
if (hundredsWheel <= 9) {
myBaggageString = [NSString stringWithFormat:#"%i", (column5[hundredsWheel][tensWheel])];
baggageWeightLabel.text = myBaggageString;
baggageWeightInt = [myBaggageString intValue];
baggageWeightFloat = [myBaggageString floatValue];
baggageMomentFloat = baggageWeightFloat * 731.10;
[self calculateWeight];
paxViewBaggageWeightLabel.text = myBaggageString;
NSLog(#"value of myBaggageString is %#", myBaggageString);
[baggagePicker reloadAllComponents];
}
if (hundredsWheel == 10){
myBaggageString = [NSString stringWithFormat:#"1000"];//, [lastFuelValues objectAtIndex: [weightPicker selectedRowInComponent:1]]];
baggageWeightLabel.text = myBaggageString;
baggageWeightInt = [myBaggageString intValue];
baggageWeightFloat = [myBaggageString floatValue];
baggageMomentFloat = baggageWeightFloat * 731.10;
[self calculateWeight];
paxViewBaggageWeightLabel.text = myBaggageString;
[baggagePicker reloadAllComponents];
}

Weirdest occurrence ever, UIButton #selector detecting right button, doing wrong 'else_if'?

So I dynamically create 3 UIButtons (for now), with this loop:
NSMutableArray *sites = [[NSMutableArray alloc] init];
NSString *one = #"Constution Center";
NSString *two = #"Franklin Court";
NSString *three = #"Presidents House";
[sites addObject: one];
[one release];
[sites addObject: two];
[two release];
[sites addObject: three];
[three release];
NSString *element;
int j = 0;
for (element in sites)
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
//setframe (where on screen)
//separation is 15px past the width (45-30)
button.frame = CGRectMake(a, b + (j*45), c, d);
[button setTitle:element forState:UIControlStateNormal];
button.backgroundColor = [SiteOneController myColor1];
[button addTarget:self action:#selector(showCCView:)
forControlEvents:UIControlEventTouchUpInside];
[button setTag:j];
[self.view addSubview: button];
j++;
}
The #Selector method is here:
- (void) showCCView:(id) sender {
UIButton *button = (UIButton *)sender;
int whichButton = button.tag;
NSString* myNewString = [NSString stringWithFormat:#"%d", whichButton];
self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
self.view.backgroundColor = [UIColor whiteColor];
UINavigationBar *cc = [SiteOneController myNavBar1:#"Constitution Center Content"];
UINavigationBar *fc = [SiteOneController myNavBar1:#"Franklin Court Content"];
UINavigationBar *ph = [SiteOneController myNavBar1:#"Presidents House Content"];
if (whichButton = 0)
{
NSLog(myNewString);
[self.view addSubview:cc];
}
else if (whichButton = 1)
{
NSLog(myNewString);
[self.view addSubview:fc];
}
else if (whichButton = 2)
{
NSLog(myNewString);
[self.view addSubview:ph];
}
}
Now, it is printing the correct button tag to NSLog, as shown in the method, however EVERY SINGLE BUTTON is displaying a navigation bar with "Franklin Court" as the title, EVERY SINGLE ONE, even though when I click button 0, it says "Button 0 clicked" in the console, but still performs the else if (whichButton = 1) code.
Am I missing something here?
You're using the = operator instead of the == operator in your conditions, which makes an assignment instead of a comparison.
Since the returned value of an assignment is the assigned value, first whichButton becomes 0 and that evaluates to false, and then whichButton becomes 1 and that evaluates to true, and no matter what you do you end up with the Franklin Court option.
You have a problem where you should have used == instead of =.
Instead of this:
if (whichButton = 0)
{
NSLog(myNewString);
[self.view addSubview:cc];
}
...
Try this:
if (whichButton == 0)
{
NSLog(myNewString);
[self.view addSubview:cc];
}
else if (whichButton == 1)
{
NSLog(myNewString);
[self.view addSubview:fc];
}
else if (whichButton == 2)
{
NSLog(myNewString);
[self.view addSubview:ph];
}
Or this:
NSLog (myNewString); //occurs in all cases.
switch (whichButton)
{
case 0:
[self.view addSubview:cc];
break;
case 1:
[self.view addSubview:fc];
break;
case 2:
[self.view addSubview:ph];
break;
default:
// optionally handle the case where the button's tag was not 0, 1, or 2.
}

How do I change the text size and component width of a UIPickerView?

I have the following code to create a UIPickerView:
pickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0.0f, 416.0f - height, 320.0f, height)];
pickerView.delegate = self;
pickerView.showsSelectionIndicator = YES;
[pickerView setSoundsEnabled:YES];
I would like to change the component widths and change the text size in each component. Is it possible to do this?
Thanks!
You can change the width by an appropriate delegate method
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component {
switch(component) {
case 0: return 22;
case 1: return 44;
case 2: return 88;
default: return 22;
}
//NOT REACHED
return 22;
}
As for a custom text size, you can use the delegate to return custom views with whatever sized text you want:
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
UILabel *retval = (id)view;
if (!retval) {
retval= [[[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, [pickerView rowSizeForComponent:component].width, [pickerView rowSizeForComponent:component].height)] autorelease];
}
retval.text = #"Demo";
retval.font = [UIFont systemFontOfSize:22];
return retval;
}
Of course you will need modify these to have appropriate values for your app, but it should get you where you need to go.