2014-09-14 3 views
1

Я создал UIPickerView, который имеет два компонента, первый компонент (A) имеет фиксированное количество строк, установленных на 13. Другой компонент (B) имеет переменное количество строк, которое в зависимости от строки, выбранной в (A).UIPickerView selectRow не работает как ожидалось

При загрузке UIPickerView я вызываю следующее, так что я могу по умолчанию выбирать оба компонента, однако проблема Im Im заключается в том, что только компонент (A) показывает правильные значения. Компонент (B) не отображает правильный набор строк или правильный выбор.

[picker selectRow:rowA inComponent:COMPONENT_A animated:YES]; 
[picker reloadAllComponents]; 
[picker selectRow:rowB inComponent:COMPONENT_B animated:YES]; 

Я попытался распечатав следующее после вызова этого кода, и кажется, что правильные значения распечатываются, но когда выбор показывает только компонент (А) показывает правильные значения и выбор.

NSLog(@"(A) - row selected: %i", [picker selectedRowInComponent:COMPONENT_A]); 
NSLog(@"(A) - number of rows: %i", [picker numberOfRowsInComponent:COMPONENT_A]); 

NSLog(@"(B) - row selected: %i", [picker selectedRowInComponent:COMPONENT_B]); 
NSLog(@"(B) - number of rows: %i", [picker numberOfRowsInComponent:COMPONENT_B]); 

Есть ли у кого-нибудь идеи относительно того, как отлаживать это или что может быть проблемой?

Update

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

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component 
{ 
    switch (component) { 
     case COMPONENT_A: 
     { 
      return 13; 
     } 
     case COMPONENT_B: 
     { 
      NSInteger selectedRowIdx = [picker selectedRowInComponent:COMPONENT_A]; 

      switch (selectedRowIdx) { 
       case A: return 2; 
       case B: return 4; 
       case C: return 6; 
       case D: return 8; 
       case E: return 10; 
       case F: return 12; 
       case G: return 14; 
       case H: return 16; 
       case I: return 18; 
       case J: return 20; 
       case K: return 22; 
       case L: return 24; 
       default: return 1; 
      } 
     } 
    } 

    return -1; 
} 


#pragma mark UIPickerViewDelegate 

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component 
{ 
    switch (component) { 
     case COMPONENT_A: 
     { 
      switch (row) { 
       case A: return @"A"; 
       case B: return @"B"; 
       case C: return @"C"; 
       case D: return @"D"; 
       case E: return @"E"; 
       case F: return @"F"; 
       case G: return @"G"; 
       case H: return @"H"; 
       case I: return @"I"; 
       case J: return @"J"; 
       case K: return @"K"; 
       case L: return @"L"; 
       default: return @""; 
      } 
     } 
     case COMPONENT_B: 
     { 
      if (row == 0) { 
       return @""; 
      } else { 
       return [NSString stringWithFormat:@"%i", (int)row]; 
      } 
     } 
    } 

    return nil; 
} 
+0

и ... что есть происходит в вашем '-: titleForRow: forComponent:' или '-viewForRow: forComponent:'? – staticVoidMan

+0

@staticVoidMan Я добавил эту информацию. –

+0

Где вы это используете? '[picker selectRow: rowA inComponent: COMPONENT_A animated: YES]; [сборщик reloadAllComponents]; [picker selectRow: rowB inComponent: COMPONENT_B animated: YES]; 'вы не должны делать это в' init', но в конечном итоге в 'viewDidLoad' – Daniele

ответ

1

Один из странных эксцентриситета UIPickerView является то, что при вызове

`[.. selectRow: inComponent: animated: ]` 

это вызовет вызов делегата

[pickerView: didSelectRow: inComponent: ] 

В результате этого она может быть легко чтобы создать непреднамеренные условия гонки, поэтому отметьте в своем деле делегата pickerView: didSelectRow: inComponent: и имейте в виду, что это вызывается в середине здесь как ar из-за установки первого компонента. Возможно, вам лучше сохранить переменную для того, что выбрано в компоненте0, и отключить ее, а не от того, что выбрано в сборщике. Вы можете также рассмотреть возможность хранения логического (listenToPicker), чтобы вы могли временно отключить его, поместив материал didSelect в , если (listenToPicker) {.....}, а затем перед его настройкой с помощью selectRow: анимированные: вызовы вы можете установить listenToPicker в NO, восстановив его на YES после того, как все компоненты будут установлены в viewDidAppear.Успехов

+2

Я не думаю, что selectRow на самом деле называет делегат didSelectRow ... – jomafer

+0

ну, и он всегда с первого sdk – Jef

+3

Я пытаюсь на iOS8 с Swift и didSelectRow не запускается ... – jomafer

4

The pickerView не похоже, чтобы получить время, чтобы дышать правильно, так что я буду предлагаю вам позволить viewDidLoad нагружают pickerView нормально, а затем сделать свой материал в -viewDidAppear:.

Ну ... вы хотите animated:YES в любом случае, так, опять же, нет смысла делать это в -viewDidLoad-viewWillAppear или даже

Попробуйте это:

-(void)viewDidAppear:(BOOL)animated 
{ 
    [picker selectRow:rowA inComponent:COMPONENT_A animated:YES]; 

    //no point reloading all components, just B 
    [picker reloadComponent:COMPONENT_B]; 

    [picker selectRow:rowB inComponent:COMPONENT_B animated:YES]; 
} 

Кроме того, место, где вы :

NSInteger selectedRowIdx = [self selectedRowInComponent:COMPONENT_A]; 

не должно быть

NSInteger selectedRowIdx = [pickerView selectedRowInComponent:COMPONENT_A]; 
0

Это может быть поздно ответ, но я просто встал вопрос и решить ее следующим образом

  1. Реализовать func pickerView(_:didSelectRow:inComponent) в вашем view controller.

  2. Вызвать следующие две функции последовательно.

    2,1 pickerView.selectRow(selectedIndex, inComponent: 0, animated: true) и

    2,2. yourViewController.pickerView(pickerView, didSelectRow: selectedIndex, inComponent: 0)

Смежные вопросы