我正在编写一个程序,该程序使用单个组件实现UIPickerView,以选择和显示来自两个阵列(时间和月份)的数据。第一个数组包含3行,第二个数组包含12.行程序首先显示包含三个项目的数组。当我选择'Month
'按钮显示第二个数组时,只显示前三个月而不是全部12个。
如果我选择'Time-of-Day'
按钮,程序会崩溃,表示:
"*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** `-[__NSArrayI objectAtIndex:]: index 3 beyond bounds [0 .. 2]'"`.
我不确定为什么它会超出数组大小。
有人可以帮我理解我需要做的事情:
'Time-Of-Day'
按钮时防止程序崩溃。以下是代码......
标题
#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
答案 0 :(得分:1)
如果组件0中当前选定的行大于2,当您将组件0翻转为表示具有3个成员的数组而不是具有12个成员的数组时,它肯定会崩溃。因此,在您从月份数组转换到上午/下午之前,您需要调用
[picker selectRow:0 inComponent:0 animated:YES]
否则,选择器将尝试选择12月的第11行,例如,每次只有三个范围异常翻转...
编辑..摘要.. UIPickerView有一个你没有考虑的变量,每个组件中当前选择的行。重新加载数据不会改变这个变量,你需要小心一点......