如何优化代码并快速加载UIPickerView数据?

时间:2014-07-17 05:44:41

标签: ios iphone optimization uipickerview xcode-instruments

我用2个组件创建UIPickerView,分钟和秒。我在UI中创建了选择器并希望用数据填充它,下面是我用0到59之间填充数字的代码。我想让它看起来像圆形,这就是为什么kSizeOfPicker是60000.当用户按下按钮时带有选择器的窗口出现但是它非常慢,因为这个 代码在viewDidLoad中。我该如何解决?

NSString *stringValue = [[NSString alloc] init];

for(int i=0; i<kSizeOfPicker; i++)
{
    stringValue = [NSString stringWithFormat:@"%d", i%60];


    [_minutesArray addObject:stringValue];
    [_secondsArray addObject:stringValue];
}

以下是数据源和委托方法:

#pragma mark - UIPickerView DataSource Methods


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


- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent :    (NSInteger)component
{

if (component==0)
{
    return [_minutesArray count];
}
else
{
    return [_secondsArray count];
}

}

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
NSString *title;
switch (component)
{

    case 0:
        title = [NSString stringWithFormat:@"%@ minutes", [_minutesArray objectAtIndex:row]];

        return title;
        break;
    case 1:
        title = [NSString stringWithFormat:@"%@ seconds", [_secondsArray objectAtIndex:row]];
        return title;
        break;
}
return nil;
}

#pragma mark - UIPickerView Delegate Methods

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{

if (component == 0)
    _firstComponent = [_minutesArray objectAtIndex:row];

else
    _secondComponent = [_secondsArray objectAtIndex:row];

}

3 个答案:

答案 0 :(得分:1)

您无需准备NSArray中的所有数据来存档循环选择器视图。 代码虚拟在所选行周围准备+ -50个重复数据集。 在pickerView:didSelectRow:inComponent:委托方法中,您可以重置所选行。

@interface MyViewController () <UIPickerViewDataSource, UIPickerViewDelegate>
@property (weak, nonatomic) IBOutlet UIPickerView *pickerView;
@property (assign, nonatomic) NSUInteger minutes;
@property (assign, nonatomic) NSUInteger seconds;
@end

@implementation MyViewController

#define VALUE_THRESHOLD 60
#define PICKER_DUPLICATES 100
#define CENTER_ROW (VALUE_THRESHOLD * PICKER_DUPLICATES / 2)

- (void)viewDidLoad {
    [super viewDidLoad];
    [_pickerView selectRow:_minutes + CENTER_ROW inComponent:0 animated:NO];
    [_pickerView selectRow:_seconds + CENTER_ROW inComponent:1 animated:NO];
}

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

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
    return VALUE_THRESHOLD * PICKER_DUPLICATES;
}

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
    return [NSString stringWithFormat:@"%d", row % VALUE_THRESHOLD];
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
    NSInteger actualRow = row % VALUE_THRESHOLD;

    // reset to center dataset
    [pickerView selectRow: actualRow + CENTER_ROW inComponent:component animated:NO];

    // do anything what you want;
    if(component == 0) {
        _minutes = actualRow;
    }
    else {
        _seconds = actualRow;
    }
}

@end

答案 1 :(得分:0)

如果由于数据繁重而导致问题是加载时间,那么您可以将这些代码放在视图中,或者您可以将代码放在Dispatch队列中,它不会阻止您的主线程并让您的屏幕快速加载。

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
    //Background Thread
    // here you can do your heavy operation 
    dispatch_async(dispatch_get_main_queue(), ^(void){
        //Update your UI
    });
});

或者,如果您只想显示时间,可以使用UIDatePicker并设置其模式:

日期选择器模式 日期选择器的模式。

typedef enum {
   UIDatePickerModeTime,
   UIDatePickerModeDate,
   UIDatePickerModeDateAndTime,
   UIDatePickerModeCountDownTimer
} UIDatePickerMode;

希望它对你有所帮助。

谢谢。

答案 2 :(得分:0)

使用UIDatePicker代替60000次迭代,它会让您的生活更轻松。将其mode设置为Time