views:

79

answers:

2

Hello!

This seems like pretty standard code straight from the doc, so I'm not sure what I am doing wrong...

My 3-component picker doesn't look right when it loads, with the selection indicator being placed too low across the picker (so the grey bar is correctly placed, but the clear raised-looking overlay is too low).

Then, when I select a row, it all works perfectly unless I select the last row, in which case it thinks I selected the next-to-the-last row.

The count of titles in the array is correct (7, for instance), and when I select rows "0-5" it works great, but when I select row "6" (the 7th row), it still thinks I am selecting "5". So both the sixth and the seventh rows will return "5" instead of "5 and 6".

This happens for all of the three components, and actually is happening in a similar way in another one of my simpler pickers elsewhere in the code (actually, with that picker, only when I come from the parent view controller. When I come from the child view controller it is fine).

Can you help?

- (void)loadmypicker {
UIPickerView *mypicker = [[UIPickerView alloc] init];
[mypicker setDataSource:self];
[mypicker setDelegate:self];
pickerTitles_Dil = [[NSArray alloc] initWithObjects:@"0", @"1", @"2", @"3", @"4", @"5", @"6", nil];
pickerTitles_Eff = [[NSArray alloc] initWithObjects:@"a", @"b", @"c", @"d", @"e", @"f", @"g", @"h", @"i", @"j", @"k", nil];
pickerTitles_Stat = [[NSArray alloc] initWithObjects:@"A", @"B", @"C", @"D", @"E", @"F", @"G", nil];
[mypicker setShowsSelectionIndicator:YES];
[mypicker selectRow:0 inComponent:0 animated:NO];
[mypicker selectRow:0 inComponent:1 animated:NO];
[mypicker selectRow:0 inComponent:2 animated:NO];
[mypicker setFrame:CGRectMake(0, 98, 320, 253)];
[self addSubview:mypicker];
    [mypicker release];
}

 - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {

if (component == 0)
    return [pickerTitles_Dil objectAtIndex:row];
else if (component == 1)
    return [pickerTitles_Eff objectAtIndex:row];
else return [pickerTitles_Stat objectAtIndex:row];
 }

 - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 3;
 }


 - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
if (component == 0)
{return [pickerTitles_Dil count];
}
else if (component == 1)
{return [pickerTitles_Eff count];
}
else 
{return [pickerTitles_Stat count];
}
   }

 - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
NSLog (@"row: %d, component :%d", row, component);
 }

Thank you for your help!

Has anyone else had this problem? To summarize, the picker shows the last row but I cannot select it. Thanks!

A: 

Somehow I think the following datasource method is deprecated, right?

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component

What happens if you try to use the following method for that?

- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view

Maybe that will help? But I am not sure this will fix it for you.

EDIT: Try something like this, the new method cannot return strings directly, but needs views:

 /* Because the UIPickerView expects a UIView for every row you insert in the UIPickerView, you need to make one. What I do here is really simple. I create a UILabel* and with each row it requests I just change the text in the UILabel. */

- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
    {
    /* Create a UILabel and set it 40 pixels to the right, to make sure it is put nicely in the UIPickerView */
        UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(40, 0, 280, 25)] autorelease];
        label.textColor = [UIColor blackColor];
        label.backgroundColor = [UIColor clearColor];

        switch (row)
        {
            default:
            case kUnderClock:
                label.text = @"Under clock";
                break;
            case kAboveSlider:
                label.text = @"Above lock slider";
                break;
            case kCenter:
                label.text = @"Vertically centered";
                break;
        }

        return label;
    }

Sorry for the indentation problem, copied this straight from my blog.

Wim Haanstra
Thanks for the response! When I replace the titleForRow line with viewForRow, I get a [NSCFString superview]: unrecognized selector sent to instance...I don't see that titleForRow is deprecated at Apple Dev, but is there a way to make this work?
snorkelt
OK, I changed the method to viewForRow (took me a while because of the 3 components and a lot of labels), but it still doesn't select the last row (if my labels go from 0-6, I can only select down to 5). Also the selection indicator is too low across the picker, so I think the problem is somewhere else in my code. The value selected is the one with a grey color across it, with the clear overlay bar lying lower than that. What can that be?
snorkelt
Did you try placing the UIPickerView at 0x0 position, to see how it reacts then?
Wim Haanstra
Yes, same problem where the picker looks wrong (with the clear selection bar lower than the grey active bar), and it won't let me select the last row.
snorkelt
I learned that if I comment out: [picker selectRow:appDelegate.dil inComponent:0 animated:NO]; [picker selectRow:(appDelegate.eff/10) inComponent:1 animated:NO]; [picker selectRow:(appDelegate.stat+4) inComponent:2 animated:NO]; then the picker looks and works fine. But, I do want the pickers to show what the current values are. Any ideas why it looks a mess with these lines in? How can I populate the pickers properly?
snorkelt
A: 

Problem fixed: picker height can be no more than 216. Because I went over at 253, all the other problems followed. Thanks!

snorkelt