I have a viewcontroller showing items from a core data entity. I also have a tableview listing records from the same entity. The table is editable, and the user could remove all the records. When this happens, the view controller holding the pickerview bombs because it's looking for records in an empty array. How to prevent this? I'm assuming I need to do something different at objectAtIndex:row...
# pragma mark PickerView Section
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1; // returns the number of columns to display.
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [profiles count]; // returns the number of rows
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
// Display the profiles we've fetched on the picker
Profiles *prof = [profiles objectAtIndex:row];
return prof.profilename;
}
//If the user chooses from the pickerview
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
selectedProfile = [[profiles objectAtIndex:row]valueForKey:#"profilename"];
}
EDIT**
Ok, I found what was causing the problem...on the PickerView I was setting a default..
self.profiles = [[self.managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
selectedProfile = [[profiles objectAtIndex:0]valueForKey:#"profilename"];
[pickerView reloadAllComponents];
When I take that out, it works like a champ.
Related
I've got a perplexing problem. I have a pickerView that closes/dismisses the view uncommanded. I can scroll to some rows fine, but others will cause the view to segue to parent view. I have tried this with a storyboard and an xib with same results. Simplifying to a clean simple project works fine, and I cannot locate the issue.
I suspect something goes on with the View Controller I cannot identify because I notice a strange happening in Storyboard Custom Class. The VC is named 'PLChooser', put that name in the custom class and it gets changed in Outline view to 'Chooser'. Something fishy is happening here and I can't find it!
I would post all the code; however, as I say the same code in a simple project works fine. Here however, is the basic protocol routines:
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component {
return [pickerArray count];
}
- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [pickerArray objectAtIndex:row];
}
- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
NSLog(#"row: %d %#",row,[pickerArray objectAtIndex:row]);
ChooserLabel.text = [pickerArray objectAtIndex:row];
}
I have an app where the user scans a QR code into an NSString, which I then need to put into a UIPickerView.
What would I use to set the text of the UIPickerView row as the NSString from the QR code?
Firstly, you need to have an array of strings and implement the UIPickerViewDataSource and UIPickerViewDelegate in your .h file. After this, you will have to make use of the delegate methods of UIPickerView like as shown :
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
//return number.
}
This will return the number of sections that you want in your pickerView.
(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return array.count;
}
The above method will return the number of rows in particular component. If you have an array, then probably it will be equal to the number of elements in your array. And finally this last one.
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
NSString *str;
if(pickerView == yourPickerName)
{
str = [array objectAtIndex:row];
}
return str;
}
This method will return the text value for each row in your picker. And don't forget to connect your pickerView's datasource and delegate in your Storyboard.
Hope this helps.
Okay, I need a picker so that a user can select from a list of predefined options. Can someone give me the easy, simplified version of how to populate a picker view from an array of NSStrings? Then, how do I read that value from the picker? I'm noticing that things like nameOfPicker.value and nameOfPicker.text do not work here.
Thank you!
I have already read the following documents and I don't really understand what they are getting at.
https://developer.apple.com/library/ios/documentation/userexperience/conceptual/UIKitUICatalog/UIPickerView.html
https://developer.apple.com/library/ios/documentation/General/Conceptual/CocoaEncyclopedia/DelegatesandDataSources/DelegatesandDataSources.html#//apple_ref/doc/uid/TP40010810-CH11
It is quite similar to how you populate data in a UITableView, by setting datasource and delegate.
1. First step is to set the delegate of the picker view. In .m file you set your datasource and delegate
#interface YourViewController () <UIPickerViewDataSource, UIPickerViewDelegate>
{
}
#property (strong, nonatomic) UIPickerView *yourPickerView;
2. Assign the datasource and delegate
self.yourPickerView.delegate = self;
self.yourPickerView.datasource = self;
3. Implement datasource and delegate
// 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.yourArrayofStrings.count;
}
//The title that should be shown in picker view
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
NSString *yourTitle = [self.yourArrayofStrings objectAtIndex:row]
return yourTitle;
}
//This is called when Picker view value is selected
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
NSLog #(#"Selected row = %#",[self.yourArrayofStrings objectAtIndex:row]);
}
I have a pickerview that loads from a core data fetch on the view controller did load method. Everything works great, however I'm finding that I'm passing null values quite often, and that I'm having to spin the picker back and forth and click several times to get the value to hold.
I also have a problem if the user doesn't manually pick something, I need it to pass the value that the picker is on. I have a datepicker on the same viewcontroller and it passes whatever date it is sitting on without any problems. I'm probably overlooking something..any help would be appreciated
# pragma mark PickerView Section
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1; // returns the number of columns to display.
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [profiles count]; // returns the number of rows
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
// Display the profiles we've fetched on the picker
Profiles *prof = [profiles objectAtIndex:row];
return prof.profilename;
}
//If the user chooses from the pickerview
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
selectedProfile = [[profiles objectAtIndex:row]valueForKey:#"profilename"];
}
# pragma mark Segue Section
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"resultsSegue"]) {
ResultsVC *result = segue.destinationViewController;
result.profileName = [NSString stringWithFormat:#"%#",selectedProfile];
NSDate *selectedDate = [datePicker date];
result.trialDate = selectedDate;
}
}
You need to initialize selectedProfile to the 1st value in the picker. Do this in viewDidLoad. This way if the user never explicitly picks a value, the selectedProfile will be set to the 1st value by default.
I have found similar questions here and here. I have tried the answers to these and other questions found on stackoverflow and Apple's developer forums, with no luck.
I created a fresh project to test this, and it works fine in that new project. I am iteratively removing differences between my new test project and the one exhibiting this issue. Any pointers would be most helpful.
I have a UIPickerView connected to my view controller. I want to initialize the UIPickerView to the last value selected by the user. However if this row is the last row in the picker, it shows the second-to-last row selected in the UI instead.
Meanwhile, logging shows the correct row index selected in the UIPickerView object instance.
Selecting any row besides the last row in the picker works fine.
I have tried calling the selectRow:inComponent:animated method from viewDidLoad, viewWillAppear, and viewDidAppear - none of these make any difference. I have also tried calling reloadAllComponents in various orders relative to row selection and data initialization - again, no difference.
Some code:
- (void)viewDidLoad
{
[super viewDidLoad];
NSParameterAssert(self.pickerView);
// Set pickerView data
self.pickerOptions = #[#"zero", #"one", #"two", #"three", #"four"];
// Picker View config
self.pickerView.dataSource = self;
self.pickerView.delegate = self;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSInteger selectedIndex = ([self.pickerOptions count] -1);
NSLog(#"About to select row: %d", selectedIndex);
[self.pickerView selectRow:selectedIndex inComponent:0 animated:NO];
NSLog(#"Selected value is %d", [self.pickerView selectedRowInComponent:0]);
}
#pragma mark UIPickerViewDataSource
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
NSInteger numRows = [self.pickerOptions count];
NSLog(#"numRows: %d", numRows);
return numRows;
}
#pragma mark UIPickerViewDelegate
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
NSString *rowTitle = [self.pickerOptions objectAtIndex:(NSUInteger)row];
return rowTitle;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
NSString *value = [self.pickerOptions objectAtIndex:(NSUInteger)row];
NSLog(#"User selected value: %#", value);
NSLog(#"index: %d", row);
}
Log output:
-[CCSelectorViewController viewDidAppear:] About to select row index: 4
-[CCSelectorViewController pickerView:numberOfRowsInComponent:] numRows: 5
-[CCSelectorViewController viewDidAppear:] Selected row index is 4
Here is the screenshot of the wrong row being selected:
http://imgur.com/FVvu9RA
This is using iOS6, XCode 4.6.1.
Any ideas?