4

UIPickerView 遇到了非常难以忍受的问题。有 2 个组件:第一个包含食物类别,第二个包含每个类别中的食物。我有适当的食物阵列,如下所示:

视图控制器.h

@property (strong, nonatomic) NSArray *leftPickerDataSource;
@property (strong, nonatomic) NSArray *vegetablesDataSource;
@property (strong, nonatomic) NSArray *eggsDataSource;
@property (strong, nonatomic) NSArray *pastaDataSource;
@property (strong, nonatomic) NSArray *riceDataSource;
@property (strong, nonatomic) NSArray *meatDataSource;

视图控制器.m

...
@implementation ViewController

@synthesize foodPicker;

@synthesize leftPickerDataSource;
@synthesize vegetablesDataSource;
@synthesize eggsDataSource;
@synthesize pastaDataSource;
@synthesize riceDataSource;
@synthesize meatDataSource;

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.leftPickerDataSource = [NSArray arrayWithObjects: @"Vegetables", @"Eggs", @"Pasta", @"Rice", @"Meat", nil];
    self.vegetablesDataSource = [NSArray arrayWithObjects:@"Potatoes", @"Broad bean", @"Beans", @"Broccoli", @"Cabbage", @"Cauliflower", @"Corn", nil];
    self.eggsDataSource = [NSArray arrayWithObjects:@"Soft-boiled", @"Hard-boiled", nil];
    self.pastaDataSource = [NSArray arrayWithObjects:@"Pasta", @"Spaghetti", nil];
    self.riceDataSource = [NSArray arrayWithObjects:@"White", @"Brown", @"Black", @"Red", nil];
    self.meatDataSource = [NSArray arrayWithObjects:@"Sausages", @"Crabs", @"Lobsters", @"Shrimps", nil];
}

我相信数组不是问题,但是当我同时旋转选择器的两个组件时,应用程序通常会因 EXC_BAD_ACCESS (Code=1...) 而崩溃。

这是我的 UIPickerView:

视图控制器.m

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

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
    if (component == 0) {
        // Left picker
        return [leftPickerDataSource count];
        //[foodPicker selectRow:0 inComponent:1 animated:YES];
    }
    else {
        // Right picker
        NSInteger sRow = [foodPicker selectedRowInComponent:0];
        if ([[leftPickerDataSource objectAtIndex:sRow] isEqual:@"Vegetables"])
            return [vegetablesDataSource count];
        else if ([[leftPickerDataSource objectAtIndex:sRow] isEqual:@"Eggs"])
            return [eggsDataSource count];
        else if ([[leftPickerDataSource objectAtIndex:sRow] isEqual:@"Pasta"])
            return [pastaDataSource count];
        else if ([[leftPickerDataSource objectAtIndex:sRow] isEqual:@"Rice"])
            return [riceDataSource count];
        else if ([[leftPickerDataSource objectAtIndex:sRow] isEqual:@"Meat"])
            return [meatDataSource count];
    }
}

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
    if (component == 0) {
        // Left picker
        return [leftPickerDataSource objectAtIndex:row];
    }
    else {
        // Right picker
        NSInteger sRow = [foodPicker selectedRowInComponent:0];
        if ([[leftPickerDataSource objectAtIndex:sRow] isEqual:@"Vegetables"])
            return [vegetablesDataSource objectAtIndex:row];
        else if ([[leftPickerDataSource objectAtIndex:sRow] isEqual:@"Eggs"])
            return [eggsDataSource objectAtIndex:row];
        else if ([[leftPickerDataSource objectAtIndex:sRow] isEqual:@"Pasta"])
            return [pastaDataSource objectAtIndex:row];
        else if ([[leftPickerDataSource objectAtIndex:sRow] isEqual:@"Rice"])
            return [riceDataSource objectAtIndex:row];
        else if ([[leftPickerDataSource objectAtIndex:sRow] isEqual:@"Meat"])
            return [meatDataSource objectAtIndex:row];
    }
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
    if (component == 0)
        [foodPicker reloadComponent:1];
}

在这里也找不到任何可疑的东西。不知道为什么,但是旋转轮子会使应用程序崩溃。我在 SO 上寻找答案,但没有任何帮助:/

你知道怎么回事吗?

4

2 回答 2

4

实际上我的假设是错误的——选定的行不是 undefined 或 nil,但是当你旋转时它会迅速变化。问题是您在 numberOfRowsInComponent 中返回的数字取决于该方法运行时旋转表盘的位置,但是到 titleForRow 运行时,第一个组件位于不同的行上,并且您尝试访问不存在的行存在。要修复它,您应该定义一个属性 sRow,在 numberOfRowsInComponent 中为其分配一个值,然后在 titleForRow 中使用相同的值(不要像现在这样重新分配),而不是获取一个新值。

@property (nonatomic) NSInteger sRow;

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
    if (component == 0) {
        // Left picker
        return [leftPickerDataSource count];
        //[foodPicker selectRow:0 inComponent:1 animated:YES];
    }
    else {
        // Right picker
        self.sRow = [foodPicker selectedRowInComponent:0];
        if ([[leftPickerDataSource objectAtIndex:self.sRow] isEqual:@"Vegetables"])
            return [vegetablesDataSource count];
        else if ([[leftPickerDataSource objectAtIndex:self.sRow] isEqual:@"Eggs"])
            return [eggsDataSource count];
        else if ([[leftPickerDataSource objectAtIndex:self.sRow] isEqual:@"Pasta"])
            return [pastaDataSource count];
        else if ([[leftPickerDataSource objectAtIndex:self.sRow] isEqual:@"Rice"])
            return [riceDataSource count];
        else if ([[leftPickerDataSource objectAtIndex:self.sRow] isEqual:@"Meat"])
            return [meatDataSource count];
    }
}

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
    if (component == 0) {
        // Left picker
        return [leftPickerDataSource objectAtIndex:row];
    }
    else {
        // Right picker
        if ([[leftPickerDataSource objectAtIndex:self.sRow] isEqual:@"Vegetables"])
            return [vegetablesDataSource objectAtIndex:row];
        else if ([[leftPickerDataSource objectAtIndex:self.sRow] isEqual:@"Eggs"])
            return [eggsDataSource objectAtIndex:row];
        else if ([[leftPickerDataSource objectAtIndex:self.sRow] isEqual:@"Pasta"])
            return [pastaDataSource objectAtIndex:row];
        else if ([[leftPickerDataSource objectAtIndex:self.sRow] isEqual:@"Rice"])
            return [riceDataSource objectAtIndex:row];
        else if ([[leftPickerDataSource objectAtIndex:self.sRow] isEqual:@"Meat"])
            return [meatDataSource objectAtIndex:row];
    }
}
于 2013-08-31T05:38:10.870 回答
2

如果您希望两者一起滚动,那么制作两个组件的目的是什么?

如果您的第一个组件值取决于第零个组件,那么理想情况下,将多个组件一起滚动应该没有任何意义。

您可以制作具有单个组件的多个选择器。

更新:还有一个选项,您可以实现这样的逻辑,直到用户选择第零个组件应用程序才会显示第一个组件,称为依赖 uipickerview。看看这个问题:问题

于 2013-08-31T05:23:52.043 回答