iOS 7中的自定义UIPickerView崩溃

时间:2013-11-26 08:33:57

标签: ios objective-c ios7 uipickerview uipicker

我做了一个Custom UIPickerView with three Components each showing label on Selection Indicator,在iOS 6中工作正常。

但我在iOS 7中遇到了崩溃。

这是我的代码:

ViewController.h

#define kDaysComponent 0
#define kHoursComponent 1
#define kMinutesComponent 2

#import <UIKit/UIKit.h>
#import "LabeledPickerView.h"

@interface ViewController : UIViewController<UIPickerViewDataSource,UIPickerViewDelegate,UITextFieldDelegate>
{
    NSMutableArray *arrDays;
    NSMutableArray *arrHours;
    NSMutableArray *arrMinutes;

    LabeledPickerView *timePicker;
    IBOutlet UITextField *txtTimeLimit;
}

@property(nonatomic, retain) NSMutableArray *arrDays;
@property(nonatomic, retain) NSMutableArray *arrHours;
@property(nonatomic, retain) NSMutableArray *arrMinutes;

ViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

@synthesize arrDays;
@synthesize arrHours;
@synthesize arrMinutes;

- (void)viewDidLoad
{

    self.arrDays = [[NSMutableArray alloc]initWithCapacity:100];
    for (NSInteger i = 0; i < 100; i++){
        [arrDays addObject:[NSString stringWithFormat:@"%d",i]];
    }
    //self.arrDays = arrDays;
    self.arrHours = [[NSMutableArray alloc]initWithCapacity:24];
    for (NSInteger i = 0; i < 24; i++){
        [arrHours addObject:[NSString stringWithFormat:@"%d",i]];
    }
    //self.arrHours = arrHours;
    self.arrMinutes = [[NSMutableArray alloc]initWithCapacity:60];
    for (NSInteger i = 0; i < 60; i++){
        [arrMinutes addObject:[NSString stringWithFormat:@"%d",i]];
    }
    //self.arrMinutes = arrMinutes;

    [self.navigationController setNavigationBarHidden:YES];

    [super viewDidLoad];


}

-(IBAction)Click:(id)sender{

    timePicker = [[LabeledPickerView alloc] init];
    timePicker.showsSelectionIndicator = YES;
    timePicker.dataSource = self;
    timePicker.delegate = self;
    [timePicker addLabel:@"Days" forComponent:kDaysComponent forLongestString:@"Hours"];
    [timePicker addLabel:@"Hours" forComponent:kHoursComponent forLongestString:@"Hours"];
    [timePicker addLabel:@"Mins" forComponent:kMinutesComponent forLongestString:@"Mins"];

    UIToolbar* toolbar = [[UIToolbar alloc] init];
    toolbar.barStyle = UIBarStyleBlackTranslucent;
    [toolbar sizeToFit];

    //to make the done button aligned to the right
    UIBarButtonItem *flexibleSpaceLeft = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
    UIBarButtonItem *flexibleSpaceRight = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];

    UIBarButtonItem* doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(doneClicked:)];


    UIBarButtonItem *unlimitedButton = [[UIBarButtonItem alloc] initWithTitle:@"Unlimited" style:UIBarButtonItemStyleBordered target:self action:@selector(unlimitedClicked:)];

    [unlimitedButton setTintColor:[UIColor colorWithRed:100.0f/255.0f green:197.0f/255.0f blue:84.0f/255.0f alpha:1.0f]];

    UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:@"Cancel" style:UIBarButtonItemStyleDone target:self action:@selector(cancelClicked:)];

    [toolbar setItems:[NSArray arrayWithObjects:cancelButton,flexibleSpaceLeft,unlimitedButton,flexibleSpaceRight,doneButton, nil]];

    //custom input view
    txtTimeLimit.inputView = timePicker;
    txtTimeLimit.inputAccessoryView = toolbar;
}
-(void)doneClicked:(id) sender
{
    [txtTimeLimit resignFirstResponder]; //hides the pickerView

    NSInteger daysRow = [timePicker selectedRowInComponent: kDaysComponent];
    NSInteger hoursRow = [timePicker selectedRowInComponent: kHoursComponent];
    NSInteger minutesRow = [timePicker selectedRowInComponent: kMinutesComponent];
    NSString *days = [arrDays objectAtIndex:daysRow];
    NSString *hours = [arrHours objectAtIndex:hoursRow];
    NSString *minutes = [arrMinutes objectAtIndex:minutesRow];

    txtTimeLimit.text = [[NSString alloc] initWithFormat:
                         @"Expires in [%@] Days [%@] Hours [%@] Minutes.",days,hours,minutes];
    if ([txtTimeLimit.text isEqualToString:@""])
    {

    }
    else
    {

    }
}

-(void)cancelClicked:(id) sender
{
    [txtTimeLimit resignFirstResponder]; //hides the pickerView
}

-(void)unlimitedClicked:(id) sender
{
    [txtTimeLimit resignFirstResponder]; //hides the pickerView
    txtTimeLimit.text = @"Select Time Limit";
}
- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark Picker View Delegate

- (NSInteger)numberOfComponentsInPickerView:(LabeledPickerView *)pickerView
{
    return 3;
}

- (NSInteger)pickerView:(LabeledPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
    if (component == kDaysComponent)
    {
        return [self.arrDays count];
    }
    else if (component == kHoursComponent)
    {
        return [self.arrHours count];
    }
    else if (component == kMinutesComponent)
    {
        return [self.arrMinutes count];
    }
    return 0;
}

- (NSString *)pickerView:(LabeledPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
    if (component == kDaysComponent)
    {
        NSLog(@"%@",[arrDays objectAtIndex:row]);
        return [self.arrDays objectAtIndex:row];
    }
    else if (component == kHoursComponent)
    {
        NSLog(@"%@",[arrHours objectAtIndex:row]);
        return [self.arrHours objectAtIndex:row];
    }
    else if (component == kMinutesComponent)
    {
        return [self.arrMinutes objectAtIndex:row];
    }
    return 0;

}

#pragma mark TEXT FIELD DELEGATE

- (BOOL)textFieldShouldBeginEditing:(UITextField *)aTextField
{
    [self Click:aTextField];
    return YES;

}

我正在显示UIPickerView作为UITextField的输入视图,并且每次我在iOS 7中都会收到此错误:

Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 5 beyond bounds [0 .. 2]'

我不知道它有什么问题。有人可以帮我这个吗?

3 个答案:

答案 0 :(得分:0)

请尝试在延迟一秒后设置txtTimeLimit.inputView。

[self performSelector:@selector(setInputView:) withObject:timePicker afterDelay:1];


- (void)setInputView:(LabeledPickerView*)picker {
   txtTimeLimit.inputView = picker;
}

我认为这与动画有关......

答案 1 :(得分:0)

你的崩溃告诉你问题是什么:

-[__NSArrayM objectAtIndex:]: index 5 beyond bounds [0 .. 2]'

当您的数组只包含3个对象时,您试图在索引5处获取对象的值。

设置一个断点并检查数组是否包含您期望的内容,并且组件值是您所期望的。

答案 2 :(得分:-1)

你必须关注一些事情,

首先是委托和数据源方法。 如果您在委托和数据源上收到警告,请更正此代码

timePicker.dataSource = (id)self;
timePicker.delegate = (id)self;

然后检查阵列。希望它能解决你的问题。