Reputation: 681
I'm creating UIPickerView with 2 components, for minutes and seconds. I've created picker in UI and want to fill it with data and below is code how I fill it with numbers from 0 - 59. I want to make it look like circular thats why kSizeOfPicker is 60000. When user press the button window with picker appears but it slows app very much, because this code is in viewDidLoad. How can I fix it?
NSString *stringValue = [[NSString alloc] init];
for(int i=0; i<kSizeOfPicker; i++)
{
stringValue = [NSString stringWithFormat:@"%d", i%60];
[_minutesArray addObject:stringValue];
[_secondsArray addObject:stringValue];
}
and here are data source and delegate methods:
#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];
}
Upvotes: 2
Views: 396
Reputation: 176
If the problem is loading time due to heavy data than either you can put these code in view did appear or you can put the code in Dispatch queue , It will not block your main thread and let your screen loads quickly.
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
});
});
Or if you want to display time only than you can use UIDatePicker and set its mode :
Date Picker Mode The mode of the date picker.
typedef enum {
UIDatePickerModeTime,
UIDatePickerModeDate,
UIDatePickerModeDateAndTime,
UIDatePickerModeCountDownTimer
} UIDatePickerMode;
Hope it helps you.
Thank you.
Upvotes: 0
Reputation: 51911
You don't need prepare all data in NSArray to archive circular pickerview.
Following code virtually prepares +-50 duplicate datasets around selected row.
In pickerView:didSelectRow:inComponent:
delegate method, you can reset selected row.
@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
Upvotes: 1
Reputation: 11233
Use UIDatePicker
instead of 60000 iterations it will make your life easier. Set its mode
to Time
.
Upvotes: 0