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!
Related
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.
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.
I am trying to create a PickerView view programatically.
I have followed all of the necessary steps however the picker just simply appears and then disappears straight away. No data can be seen.
I am setting the delegate and data source and I have implemented the necessary methods.
Here is my code:
in .h
#interface NJATimeEntryViewController : UIViewController <UIPickerViewDelegate, UIPickerViewDataSource>
#property (nonatomic, strong) UIPickerView *customerPicker;
#property (nonatomic, strong) NSArray *pickerTitles;
#end
in .m
- (void)viewDidLoad
{
[super viewDidLoad];
self.pickerTitles = #[#"ONE", #"TWO", #"THREE"];
self.customerPicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 200, 320, 200)];
self.customerPicker.dataSource = self;
self.customerPicker.delegate = self;
[self.view addSubview:self.customerPicker];
}
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return self.pickerTitles.count;
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [[self pickerTitles] objectAtIndex:row];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
NSLog(#"Selected Row %d", row);
}
All help is appreciated thanks.
FIXED:
All i did was set the background color of the view controllers view and now it works. I see this as a bug as no where is it stated that the background color has to be set.
Set Some Background color ( except black )of your view, then try,
self.view.backgroundColor=[UIColor yellowColor];
Hopefully this is an easy one.
Here's the deal: I've got a button item, "Select", that opens a picker. When the user selects something from the picker, the title of "Select" button changes to the selection and the picker animates out of view. Now I've created a second "Search" button that will query the Google Places API, but I need it to NOT query ITS title as its doing now, but the title of the OTHER button. Make sense?
This is the relevant code. I'm positive it's a simple tweak, but I'm new to Objective-C, so I'm still wrapping my head around how things operate.
ViewController.m
#import "RendezvousViewController.h"
#interface RendezvousViewController ()
#end
#implementation RendezvousViewController
// returns the number of 'columns' to display.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [self.userSelectArray count];
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [self.userSelectArray objectAtIndex:row];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
NSLog(#"Selected Row %ld", (long)row);
switch(row)
{
case 0:
self.userSelection.title = #"Breakfast";
break;
case 1:
self.userSelection.title = #"Brunch";
break;
case 2:
self.userSelection.title = #"Lunch";
break;
case 3:
self.userSelection.title = #"Dinner";
break;
case 4:
self.userSelection.title = #"Bar";
break;
case 5:
self.userSelection.title = #"Late Night Snack";
break;
}
}
-(void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.userSelectArray = [[NSArray alloc] initWithObjects:#"Breakfast",#"Brunch",#"Lunch",#"Dinner",#"Bar",#"Late Night Snack" , nil];
//Make this controller the delegate for the map view.
self.mapView.delegate = self;
// Ensure that you can view your own location in the map view.
[self.mapView setShowsUserLocation:YES];
//Instantiate a location object.
locationManager = [[CLLocationManager alloc] init];
//Make this controller the delegate for the location manager.
[locationManager setDelegate:self];
//Set some parameters for the location object.
[locationManager setDistanceFilter:kCLDistanceFilterNone];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
firstLaunch=YES;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)toolbarButtonPress:(id)sender {
UIBarButtonItem *button = (UIBarButtonItem *)sender;
NSString *buttonTitle = [button.title lowercaseString];
[self queryGooglePlaces:buttonTitle];
//Use the above title text to build the URL query and get the data from Google.
}
ViewController.m
#interface RendezvousViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate, UIPickerViewDataSource,UIPickerViewDelegate>
{
CLLocationManager *locationManager;
CLLocationCoordinate2D currentCentre;
int currenDist;
BOOL firstLaunch;
}
#property (strong, nonatomic) IBOutlet MKMapView *mapView;
#property (strong, nonatomic) IBOutlet UIBarButtonItem *userSelection;
#property (strong, nonatomic) IBOutlet UIBarButtonItem *searchButton;
#property (strong, nonatomic) IBOutlet UIPickerView *userPicker;
#property (strong, nonatomic) NSArray *userSelectArray;
#end
As always, thanks in advance.
If you make the button a property on your view, you could just access it directly (instead of using sender).
But why not get it directly from the picker instead of indirectly from the button title?
EDIT:
So based on your code, you want to add another button
#implementation RendezvousViewController{
UIButton *selectButton;
}
Initalize it
-(void)viewDidLoad {
selectButton = [[UIButton alloc] init];
...
}
Then set the title in the picker
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
NSLog(#"Selected Row %ld", (long)row);
switch(row)
{
case 0:
self.selectButton.title = #"Breakfast";
break;
...
}
}
Then grab it when your other button is selected:
- (IBAction)toolbarButtonPress:(id)sender {
NSString *buttonTitle = [self.selectButton.title lowercaseString];
[self queryGooglePlaces:buttonTitle];
//Use the above title text to build the URL query and get the data from Google.
}
#implementation RendezvousViewController{
UIButton *selectButton;
NSString *selection;
}
I would suggest however, to have another property to just store the value that was selected instead of relying on your UI, like the button title. It would look like this:
Initalize it
-(void)viewDidLoad {
selectButton = [[UIButton alloc] init];
selection = #"";
...
}
Then set the title in the picker
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
NSLog(#"Selected Row %ld", (long)row);
switch(row)
{
case 0:
selection = #"Breakfast";
break;
...
}
self.selectButton.title = selection;
}
Then grab it when your other button is selected:
- (IBAction)toolbarButtonPress:(id)sender {
[self queryGooglePlaces:selection];
//Use the above title text to build the URL query and get the data from Google.
}
if([buttonTitle isEqualToString:"Select"])
return; //no searching
else{
[self queryGooglePlaces:buttonTitle];
}
I just updated my project to ios6 and discovered that my UIPicker is no longer displaying the data in it. I really don't know what I could do to make sure that it does again. Any suggestions?
AddRoleTVC.h
#import <UIKit/UIKit.h>
#interface AddRoleTVC : UITableViewController <UIPickerViewDataSource, UIPickerViewDelegate> {
IBOutlet UIPickerView *pickerView;
NSMutableArray *arrayColors;
}
#end
AddRoleTVC.m
#import "AddRoleTVC.h"
#import "UIAlertView+error.h"
#import "API.h"
#include <CommonCrypto/CommonDigest.h>
#implementation AddRoleTVC
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
arrayColors = [[NSMutableArray alloc] init];
[arrayColors addObject:#"Red"];
[arrayColors addObject:#"Orange"];
[arrayColors addObject:#"Yellow"];
[arrayColors addObject:#"Green"];
[arrayColors addObject:#"Blue"];
[arrayColors addObject:#"Indigo"];
[arrayColors addObject:#"Violet"];
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component {
return [arrayColors count];
}
- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [arrayColors objectAtIndex:row];
}
- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
NSLog(#"Selected Color: %#. Index of selected color: %i", [arrayColors objectAtIndex:row], row);
}
#end
You used the IBOutlet To Picker View, so You set Delegate and datasource in your .Xib File. It must work.