How to optimize code and load UIPickerView with data fast? - ios

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];
}

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

Use UIDatePicker instead of 60000 iterations it will make your life easier. Set its mode to Time.

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.

Related

UIPickerView goes back to row 0 when released

I added a UIPickerView to a UITableViewCell. I am adding about 5 entries to it. Now when I try to select a value, the - (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component function is called with the correct row. But on the scrren the UIPickerView "scrolls" back to the first element and does not stick to the selected value.
Anyone had the same problem?
EventSelectCell.h
#class EventSelectCell;
#protocol EventSelectCellDelegate <NSObject>
- (void)selectedEvent:(Event*)selectedEvent;
#end
#interface EventSelectCell : UITableViewCell <UIPickerViewDataSource, UIPickerViewDelegate>
#property (strong, nonatomic) id <EventSelectCellDelegate> delegate;
#property (weak, nonatomic) IBOutlet UIPickerView *selectWheel;
#end
EventSelectCell.m
#import "EventSelectCell.h"
#implementation EventSelectCell
{
EventManager* eventManager;
NSArray* listOfEvents;
}
- (void)awakeFromNib {
self.selectWheel.delegate = self;
self.selectWheel.dataSource = self;
// get the EventManger
eventManager = [EventManager sharedEventManager];
listOfEvents = [eventManager getListOfEvents];
[self.selectWheel reloadAllComponents];
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component {
return [listOfEvents count];
}
- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
Event* selectedEvent = [listOfEvents objectAtIndex:row];
return [selectedEvent name];
}
- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
Event* selectedEvent = [listOfEvents objectAtIndex:row];
[self.delegate selectedEvent:selectedEvent];
}
#end
the delegate
- (void)selectedEvent:(Event*)selectedEvent {
[playersInGame removeAllObjects];
[playersInGame addObjectsFromArray:[self.eventManager getPlayersInEvent:selectedEvent onlyActive:YES]];
[selectedEvent setIsActive:[NSNumber numberWithInt:1]];
activeEvent = selectedEvent;
[self.tableView reloadData];
}
Okay, I found the problem. The UIPickerView is in a UITableViewCell. Whenever someone selected something with the UIPickerView I called [self.tableView reloadData], this caused the table to reload and also initialized the UIPickerView again.
Now I am just reloading a singel section in the table.

ios/xcode/objective-c: UIPickerView Not Displaying

I have a UIPickerView that shows up in storyboard but is invisible or at best a colored block if I change the background color when I compile the program. Do I need to populate it with data for it to display, i.e. does it no longer show Cupertino, Mountain View etc. once compiled?
BTW, I am trying to populate picker view with data but still invisible:
code:
in .h file:
#interface pickerVC : UIViewController<UIPickerViewDelegate,UIPickerViewDataSource>
#property (weak, nonatomic) IBOutlet UIPickerView *pickerView;
#property (strong, nonatomic) IBOutlet UILabel *color;
#property (strong, nonatomic) NSArray *myArray;
in viewdidload;
UIPickerView *pickerView;
pickerView.delegate = self;
_myArray = [[NSArray alloc] initWithObjects:#"Blue",#"Green",#"Orange",#"Purple",#"Red",#"Yellow" , nil];
//PICKER METHODS
// tell the picker how many rows are available for a given component
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
// NSUInteger numRows = 3;
return _myArray.count;
}
// tell the picker how many components it will have
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
// tell the picker the title for a given component
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
NSString *title;
title = _myArray[row];
return title;
}
// tell the picker the width of each row for a given component
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component {
int sectionWidth = 300;
return sectionWidth;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow: (NSInteger)row inComponent:(NSInteger)component{
NSLog(#"Selected Row %d", row);
switch(row){
// Handle the selection
}
yes, you need to implement the data source and picker view delegates.
Yes it is not displaying. You have to set delegate and datasource of picker view and implement delegate methods in your controller.m file.
e.g.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return 10;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return #"ABC";
}
First of all add this
<UIPickerViewDelegate,UIPickerViewDataSource> in your .h file
after that add there Delegate Methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return 5;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return #"xyz";
}

Xcode Cocoa default picker animation not animating for iOS app

So I've followed everything this post Default Picker Value iphone says, but I can't seem to get my picker to work.
Here's my .m snippet:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.arrPercent = #[#"1",#"2",#"3",#"4",#"5",#"6",#"7",#"8",#"9",#"10",#"11",#"12",#"13",#"14",#"15",#"16",#"17",#"18",#"19",#"20",#"21",#"22",#"23",#"24",#"25",#"26",#"27",#"28",#"29",#"30",#"31",#"32",#"33",#"34",#"35",#"36",#"37",#"38",#"39",#"40",#"41",#"42",#"43",#"44",#"45",#"46",#"47",#"48",#"49",#"50"];
self.arrPeople = #[#"1",#"2",#"3",#"4",#"5",#"6",#"7",#"8",#"9",#"10",#"11",#"12",#"13",#"14",#"15",#"16",#"17",#"18",#"19",#"20"];
self.percent = [NSNumber numberWithInt:15];
self.people = [NSNumber numberWithInt:5];
self.strSubTotal = #"";
self.myPicker.dataSource = self;
self.myPicker.delegate = self;
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
//[self.myPicker selectRow:self.percent.integerValue inComponent:0 animated:YES];
[self.myPicker selectRow:5 inComponent:0 animated:YES];
[self.myPicker selectRow:5 inComponent:1 animated:YES];
[self.myPicker reloadAllComponents]; // tried commenting out this line with no luck
}
Here's my .h snippet:
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#interface ViewController : UIViewController <UIPickerViewDataSource,UIPickerViewDelegate>
#property (nonatomic,strong) NSArray *arrPercent;
#property (nonatomic,strong) NSArray *arrPeople;
#property (strong, nonatomic) IBOutlet UIPickerView *myPicker;
#property (strong, nonatomic) NSString *strSubTotal;
#property (strong, nonatomic) NSNumber *percent;
#property (strong, nonatomic) NSNumber *people;
#end
Here's the delegate stuff, I think...
// returns the number of 'columns' to display.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 2;
}
// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent: (NSInteger)component
{
if(component== 0)
{
return [self.arrPercent count];
}
else
{
return [self.arrPeople count];
}
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if(component == 0)
{
return [NSString stringWithFormat:#"%#%#", [self.arrPercent objectAtIndex:row], #"%"];
}
else
{
return [self.arrPeople objectAtIndex:row];
}
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if(component == 0)
{
self.percent = [self.arrPercent objectAtIndex:row];
}
else
{
self.people = [self.arrPeople objectAtIndex:row];
}
[self updateSubTotal:-3];
}
When I start the emulator, the picker doesn't animate to the position I tell it to. Am I doing anything wrong? Please help!
As it turns out, the error was that for some reason, the connection between the picker in the UI was disconnected with the code. I had to hold the Control key while dragging the picker from the UI to the .h file.
I saw this because I noticed a little "empty button icon" next to the method declaration in the .h file. Once Xcode understood that the picker is controlled by the piece of code, everything works as expected.
Thank you so much!

Custom UITextLabel with picker wont display numbers when tapped on

Similar to how amazon does for selecting quantity of an item. I want it to then save the number to display in another tableview. Here is the code I have for my .m file. When I click on the text field the picker is empty.
#interface ApparelViewController ()
#property(nonatomic, readonly) NSInteger numberOfComponents;
#end
#implementation ApparelViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIPickerView *picker = [[UIPickerView alloc] init];
self.quantity.inputView = picker;
//creating the arrays for the values in the picker wheel
self.quantity0 = #[#1, #2, #3, #4, #5];
}
//custom picker in text field
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return self.quantity0.count;
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow: (NSInteger)row forComponent:(NSInteger)component {
return self.quantity0[row];
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
self.quantity.text = self.quantity0[row];
[self.quantity resignFirstResponder];
}
Looks like you forgot to set the UIPicker's delegate to self.
In your viewDidLoad, try this:
picker.delegate = self;

change language programmatically using UIPicker IOS

how to change the language in IOS using UIPicker?
Languages: English, Chinese (Simplified), Bahasa Malaysia
When user selects Chinese (Simplified) it changes the contents of the labels based on languages above.
here's the code
ChangeLanguage.h
#interface ChangeLanguageViewController :UIViewController<UIPickerViewDataSource UIPickerViewDelegate>
#property (nonatomic, strong)IBOutlet UIPickerView *myPickerView;
#oroperty (nonatomic, strong)NSArray *languageArray;
#import "ChangeLanguageViewController.h"
#interface ChangeLanguageViewController ()
#end
- (void)viewDidLoad
{
myPickerView.delegate = self;
myPickerView.dataSource = self;
languageArray = [[NSArray alloc] initWithObjects:#"English", #"Chinese (Simplified)", #"Bahasa
Malaysia", nil];
#pragma mark - UIPickerView Delegate
//return the number of columns to display
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
//returns the number of rows in each component.
-(NSInteger)pickerView:(UIPicker *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [languageArray count];
#pragma mark -UIPickerView Delegate
-(CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component
{
return 30.0;
}
-(NSString *)pickerView:(UIPicker *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [languageArray objectAtIndex:row];
}

Resources