在一个UIPickerView组件中显示来自2个阵列的数据

时间:2014-01-25 18:49:55

标签: uipickerview

我正在编写一个程序,该程序使用单个组件实现UIPickerView,以选择和显示来自两个阵列(时间和月份)的数据。第一个数组包含3行,第二个数组包含12.行程序首先显示包含三个项目的数组。当我选择'Month'按钮显示第二个数组时,只显示前三个月而不是全部12个。

如果我选择'Time-of-Day'按钮,程序会崩溃,表示:

"*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** `-[__NSArrayI objectAtIndex:]: index 3 beyond bounds [0 .. 2]'"`.

我不确定为什么它会超出数组大小。

有人可以帮我理解我需要做的事情:

  1. 更正我的代码以允许选择器视图在选择“月份”按钮时显示所有12个月
  2. 在显示月份后,在选择'Time-Of-Day'按钮时防止程序崩溃。
  3. 以下是代码......

    标题

    #import <UIKit/UIKit.h>
    
    @interface ViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate>
    
    @property (strong, nonatomic) IBOutlet UITextField *todTxtField;
    @property (strong, nonatomic) IBOutlet UITextField *monthTxtField;
    
    @property (strong, nonatomic) NSArray *todArray;
    @property (strong, nonatomic) NSArray *monthArray;
    
    @property (strong, nonatomic) IBOutlet UIPickerView *thePickerView;
    
    - (IBAction)monthBtnAction:(id)sender;
    - (IBAction)todBtnAction:(id)sender;
    
    @end
    

    实施

    #import "ViewController.h"
    
    @interface ViewController () 
    @end
    
    @implementation ViewController
    
    @synthesize todArray, monthArray;
    @synthesize thePickerView;
    @synthesize monthTxtField, todTxtField;
    
    int buttonTouched = 0;
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        self.todArray = [[NSArray alloc] initWithObjects:@"AM", @"Mid-Day", @"PM", nil];
        self.monthArray =[[NSArray alloc] initWithObjects: @"January", @"February", @"March", @"April",  @"May",  @"June", @"July", @"August", @"September", @"October", @"November", @"December", nil];
    }
    
    - (void) viewDidAppear:(BOOL)animated
    {
        //set default rows of UITextFields to an initial state
        monthTxtField.text = @"January";
        todTxtField.text = @"Mid-Day";
    }
    
    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    #pragma mark Button Actions
    
    - (IBAction)todBtnAction:(id)sender
    {
        buttonTouched = 0;
        [thePickerView reloadAllComponents];
    }
    
    - (IBAction)monthBtnAction:(id)sender
    {
        buttonTouched = 1;
        [thePickerView reloadAllComponents];
    }
    
    #pragma mark Picker
    
    // returns the number of components to be used
    - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
    {
        return 1;
    }
    
    
    // returns the # of rows in the components
    - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:NSInteger)component
    {
        switch (buttonTouched)
        {
            case 0:
                return [todArray count];
                break;
            default:
                return [monthArray count];
                break;
        }
    }
    
    //Display the row number from the array
    - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
    {
        switch (buttonTouched)
        {
            case 0:
                return [todArray objectAtIndex:row];
                break;
            default:
                return [monthArray objectAtIndex:row];
                break;
         }
    }
    
    //Display the row content from the array
    - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
    {
        switch (buttonTouched)
        {
            case 0:
               self.todTxtField.text = [todArray objectAtIndex:row];
               break;
            default:
               self.monthTxtField.text = [monthArray objectAtIndex:row];
               break;
         }
    }
    
    @end
    

1 个答案:

答案 0 :(得分:1)

如果组件0中当前选定的行大于2,当您将组件0翻转为表示具有3个成员的数组而不是具有12个成员的数组时,它肯定会崩溃。因此,在您从月份数组转换到上午/下午之前,您需要调用

[picker selectRow:0 inComponent:0 animated:YES]

否则,选择器将尝试选择12月的第11行,例如,每次只有三个范围异常翻转...

编辑..摘要.. UIPickerView有一个你没有考虑的变量,每个组件中当前选择的行。重新加载数据不会改变这个变量,你需要小心一点......