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.
Related
I'm looking for a spinner control something similar to this for ios:
http://github.hubspot.com/odometer/docs/welcome/
can't find anything so far, please share if you know any.
there is one third party library , by which you can do this https://github.com/Rizh/RCounter
https://github.com/naked-apps/NACounter
https://github.com/jonathantribouharet/JTNumberScrollAnimatedView
The nearest thing in iOS, similar to this is UIPickerView. You can create a UIPickerView in the Interface Builder or through code.
Next, make your class conform to UIPickerViewDataSource and UIPickerViewDelegate.
In your viewDidLoad: method, assign the delegate and dataSource of the UIPickerView to the respective class.
And finally add the following methods to your class.
// The number of columns of data
- (int)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 5;
}
// The number of rows of data
- (int)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return 10;
}
// The data to return for the row and component (column) that's being passed in
- (NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [NSString stringWithFormat:#"%ul",row];
}
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'm currently working on my first "big" project. The project is a simpel converter for different currencies. I wonder if it is possible to in some way invert the two arrays. I don't know how I should implement the if statement. Becouse if i put it in the title for row method i'm will probably get the control may reach non-void error message. I may explain this pretty bad but i just started programming.
if(!reverse) { // do nothing } else {
// swap the two pickerviews
}
//Toggle reverse on/off <->
- (IBAction)Reverse:(id)sender {
reverse = (reverse+1)%2;
NSLog(#"%d",reverse);
}
//what title for row
-(NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
if (component == 0) {
return [Datarray objectAtIndex:row];
}
return [Datarray2 objectAtIndex:row];
}
I see what you're trying to do. Instead of having two or multiple PickerViews. Just change the DataSource and reload the PickerView. if you only have two currencies just use a flag, otherwise create a NS_ENUM to identify which array the PickerView DataSource should use and in the DataSource methods like, pickerView:titleForRow:forComponent: use a switch case of if-else statements to identify the correct dataSource array.
// .h file
typedef NS_ENUM (NSInteger, CURRENCY_TYPE) {
CURRENCY_TYPE_US,
CURRENCY_TYPE_DK
};
#property (nonatomic, strong) NSArray *dataArrayUS; // In this example, these arrays contains NSStrings
#property (nonatomic, strong) NSArray *dataArrayDK;
#property (nonatomic) CURRENCY_TYPE currencyType;
// .m file
-(NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
switch (self.currencyType) {
case CURRENCY_TYPE_US:
return self.dataArrayUS[row];
break;
case CURRENCY_TYPE_DK:
return self.dataArrayDK[row];
break;
}
}
- (IBAction)currencyChangingAction:(id)sender
{
// Add some logic that changes to the self.currencyType to the correct currency.
self.currencyType = CURRENCY_TYPE_US; // or _DK
// And Reload Picker
}
EDITED:
Is this what you want? - This will only work if you have two Arrays though.
//what title for row
- (NSString *) pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return (component == 0) ? [Datarray objectAtIndex:row] : [Datarray2 objectAtIndex:row];
}
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.
I'm attempting to update a single UIPickerView with a different NSArray of data based on which Index is selected from a UISegmentedControl. Currently when I change the control the numberOfRowsInComponent does not update, and the titleForRow will only update when scrolling the picker.
The NSArrays are populated within viewDidLoad, and I'm using the reloadAllComponents method upon an IBAction of the SegmentedControl.
#synthesize subnetView, classControl;
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
//One column
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
//set number of rows
if (classControl.selectedSegmentIndex == 0){
NSLog(#"Class A Rows %d", [classAArray count]);
return classAArray.count;
}
else if (classControl.selectedSegmentIndex == 1){
return classBArray.count;
}
else if (classControl.selectedSegmentIndex == 2){
return classCArray.count;
}
return 0;
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
//set item per row
if (classControl.selectedSegmentIndex == 0){
NSLog(#"Class A Rows %d", [classAArray count]);
return [classAArray objectAtIndex:row];
}
else if (classControl.selectedSegmentIndex == 1){
return [classBArray objectAtIndex:row];
}
else if (classControl.selectedSegmentIndex == 2){
return [classCArray objectAtIndex:row];
}
return 0;
}
-(IBAction)classChange{
[subnetView reloadAllComponents];
}
Based on which selector is chosen to be "selected" within interface builder, the picker is loaded with the correct array and number of rows. Based on this code when selecting an array with less elements, the numberOfRowsInComponents is not being updated, and the app will crash when reaching the end of the smaller array.
So my two problems:
Updating of elements only occurs when scrolling.
The number of rows does not update when performing the reloadAllComponents method.
Thanks for listening!
I've seen this before. Usually it is caused by the pickerview outlet not being connected, effectively calling reloadAllComponents on nothing. But when you scroll the connected data source and delegate methods still work.
This can be easily checked by login the outlet's value using:
NSLog(#"%#",subnetView);
If it logs (NULL) as I expect it will simply connect your IB outlet and you're done.