UIPickerView displays an application failure message when a user hides components at the same time

I have a really unbearable problem with UIPickerView. There are 2 components: the first with food categories, and secondly, the products in each category. I have the correct arrays with products that look like this:

ViewController.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; 

ViewController.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]; } 

I believe arrays are not a problem, but when I spin two components of the collector at the same time, the application usually crashes with EXC_BAD_ACCESS (Code = 1 ...).

Here is my UIPickerView:

ViewController.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]; } 

Nothing suspicious can be found here. I do not know why, but the rotation of the wheels is a failure of the application. I searched for answers on SO but nothing helps: /

Do you have any idea what this is?

+4
source share
2 answers

Actually, I was mistaken in my assumption - the selected line is not undefined or zero, but it changes quickly during rotation. The problem is that the number you return to numberOfRowsInComponent depends on where the spinning disk is located, when this method starts, but by the time the titleForRow header is working, the first component is on a different line and you are trying to access lines that do not exist. To fix this, you must define the sRow property, assign it a value in numberOfRowsInComponent, and then use the same value (do not overwrite it as it is now) in titleForRow, and not get a new value.

 @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]; } } 
+4
source

If you want both to scroll together, what is the purpose of creating the two components?

If your first component values ​​depend on the zero component, then ideally there should be no point in scrolling several components together.

You can make several assemblers having one component.

Update : Another option, you can implement the logic in such a way that until the user selects the zero component application, the first component called the dependent uipickerview will not be displayed. Take a look at this question: Question

+2
source

Source: https://habr.com/ru/post/1499893/


All Articles