My problem is about set new data to my UIPickerView from another ViewController. I have main.storyboard(ViewController.h and ViewController.m), I have a pickerview(I call it aPicker) in it. I have a CustomTableViewController to load some images. When I tap on these images, data of aPicker will change.
aPicker in ViewController.m
- (NSInteger)numberOfComponentsInPickerView: (UIPickerView *)pickerView;{
return 1;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
if(pickerView== aPicker)
{
//I will code it later
}
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;{
if(pickerView==aPicker)
{
return [aPickerAdapter count];
}
}
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view{
UIView* tmpView= [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 32)];
UILabel *lbl;
if(pickerView==aPicker)
{
lbl = [[UILabel alloc] initWithFrame:CGRectMake(64, 0, 256, 32)];
[lbl setText:[aPickerAdapter objectAtIndex:row]];
}
[tmpView insertSubview:lbl atIndex:0];
return tmpView;
}
I call custom table here:
NSMutableArray* tranferData= [[NSMutableArray alloc] init];
[tranferData addObject:aPickerAdapter];
[tranferData addObject:aPicker];
[tranferData addObject:self];
aPicker.delegate=self;
[tranferData addObject:aPicker.delegate];
aPicker.dataSource=self;
[tranferData addObject:aPicker.dataSource];
customTableViewController=[[CustomTableViewController alloc] initWithNibName:#"CustomTableViewController" bundle:[NSBundle mainBundle] set:tranferData];
customTableViewController.delegate=self;
[self.view addSubview:customTableViewController.view];
Receive in CustomTableViewController.m
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil set:(NSMutableArray *)myarray{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
myArray=myarray;
// Custom initialization on passed parameter observation object
aPickerAdapter=[myarray objectAtIndex:0];
aPicker=[myarray objectAtIndex:1];
tranferSeft=[myarray objectAtIndex:2];
pickerDelegate=[myarray objectAtIndex:3];
pickerDataSource=[myarray objectAtIndex:4];
}
return self;
}
When tap image in table
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *string= [#"tap to row " stringByAppendingString:[NSString stringWithFormat:#"%d",indexPath.row]];
NSLog(string);
//NSString *str= [onlineIdList objectAtIndex:indexPath.row];
//UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Demo" message:str delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
//[alert show];
NSMutableArray *testArr= [[NSMutableArray alloc]init];
[testArr addObject:#"2"];
[testArr addObject:#"4"];
[testArr addObject:#"6"];
//aPicker.delegate= pickerDelegate;
//aPicker.dataSource= pickerDataSource;
**aPickerAdapter=testArr;
[aPicker reloadAllComponents];**
[self hideAndShowSubChannel];//this funtion is to hide and show aPicker, defaut aPicker is hide, on first tap it will show([aPicker setHidden:NO]), and it hide on second tap....
}
When I tap to image, picker only hide and show(I think it mean my program can understand the pointer point to aPicker),but it can't add data from my testArr to aPicker, I also try to reset delegate and datasource received, it till not works. I test with the same code(create testArr, set aPickerAdapter, reloadAllComponent... )in ViewController.m, it works. Why I can't reload it? Help me please!
ps: I'm just a newbie and not good at English. If I have any mistake, please forgive me, thanks
I would do it differently. You are trying to have your TableViewController update another view controller's view directly - you shouldn't. You need instead to pass the data back to your first view controller, so that it can update its own views. There are various techniques for this (see this link), but in your circumstances I would implement a method in your view controller and call it from your custom TableViewController:
In ViewController:
-(void)updatePicker:(NSArray *)newArray {
aPickerAdapter = testArr;
[aPicker reloadAllComponents]
// and do anything else you need
}
In your CustomerTableViewController didSelectRow method:
[self.delegate updatePicker:testArr];
I've solved it by the way of #pbasdf anh his link
(answer of #Matt Price really useful). Tks all :D
Try implementing the UIPickerViewDelegate-Method
(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
instead of the viewForRow-method.
For example like this:
- (NSString *)pickerview:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [aPickerAdapter objectAtIndex:row];
}
Related
I would like the user to be able to change the title of a button this is a hardcoded example of what I intend to do:
[myButton setTitle:#"B" forState:UIControlStateNormal];
However, I would rather prompt the user with a UIPicker, and allow the user to choose from many options in order to change the title.
- (IBAction)handleLongPress:(UILongPressGestureRecognizer *)sender {
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:#selector(handleLongPress:)];
lpgr.minimumPressDuration = 1.0;
if ([sender.view isKindOfClass:[UIButton class]]) {
NSLog(#"user has clicked the button%#", sender.view);
UIButton *myButton = (UIButton *)sender.view;
UIPickerView *picker = [[UIPickerView alloc] init];
myButton.titleLabel = picker;
}
}
At this point I see an error *assignment to readonly property Is it possible to use the UIPickerView in conjunction with the setTitle property of UIButton? If so how is this accomplished?
The error is obvious:
titleLabel is a UILabel property of the UIButton class, and it is read-only (you cannot set it to another value). You need to use its label's text property instead:
myButton.titleLabel.text = #"some text";
and not:
myButton.titleLabel = picker;
or
myButton.titleLabel.text = picker;
because picker is not an NSString object.
Let me explain in a minute how to implement this...
In your View Controller class, create a property (I recommend to do it in the private interface), and also implement the UIPickerViewDataSource, UIPickerViewDelegate protocols:
#interface PPMyViewController () <UIPickerViewDataSource, UIPickerViewDelegate>
#property (nonatomic, strong) UIPickerView *pickerView;
#end
Now, use lazy instantiation for the pickerView property:
- (UIPickerView *)pickerView
{
if (!_pickerView)
{
_pickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 0, 320, 100)];
_pickerView.dataSource = self;
_pickerView.delegate = self;
}
return _pickerView;
}
Make sure you add to the main view, you can do it in the viewDidLoad method:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view addSubview:self.pickerView];
}
And implement most of the 2 protocols methods:
#pragma mark - UIPickerViewDataSource Methods
// 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 10;
}
#pragma mark - UIPickerViewDelegate Methods
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component;
{
return 200;
}
- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component
{
return 50;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [NSString stringWithFormat:#"row %d", row];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
NSLog(#"Row %d selected", row);
// myButton.titleLabel.text = #"text you need depending on row selection";
}
Notice that my code will make the UIPickerView visible at the bottom all the times. You may hide/unhide it as needed. Or better, use animation to position it off-screen instead of hiding.
You cannot do this like you attempt to. What you need to do is listen to the user's tap of the button, and then present a picker to the user.
There are open source controls that can simplify this, such as ActionSheetPicker.
Let me preface by saying that I am completely new to programming. I have also done a bunch of searching on this issue and haven't found an answer that seems to address exactly what I am doing.
The result I am looking for is a text field that can be populated by the user by using a pickerView. After putting a UITextView box in the .xib file I am not sure how make it call a pickerView when tapped and then populate from that picker view.
Thank you for any help given. Let me know if I need to clarify more.
Create a UIPickerView and set it as the inputView property of your UITextView. Then, register your class for the dataSource/delegate of the UIPickerView to populate it and know when it has changed selection. Below is a simple solution for a picker with a single component.
SomeViewController.h:
#interface SomeViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate>
{
UIPickerView *picker;
NSArray *dataSource;
}
SomeViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
picker = [[UIPickerView alloc] init];
picker.dataSource = self;
picker.delegate = self;
myTextView.inputView = picker;
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [dataSource count];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [dataSource objectAtIndex:row];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
[myTextView setText:[dataSource objectAtIndex:row]];
}
I attempted to build a basic application prototype (mimic real application flow). I created one view controller class and linked the UIPickerView to the .h file. Wrote the logic but still nothing is reflecting in the picker.
Am I missing something? Here you go with the code:
#implementation SelectCountryForViewAdsViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1; // For one column
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [self.colorArray count];
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [self.colorArray objectAtIndex:row]; // If it's a string
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.colorArray = [[NSArray alloc] initWithObjects:#"Blue",#"Green",#"Orange",#"Purple",#"Red",#"Yellow" , nil];
}
and in the .h file:
#interface SelectCountryForViewAdsViewController : UIViewController <UIPickerViewDataSource,UIPickerViewDelegate>
#property (strong, nonatomic) IBOutlet UIPickerView *countrySelector;
#property (strong, nonatomic) NSArray *colorArray;
#end
Any help is appreciated. I am a beginner in iOS devs.
Please check below image you need to right click on UIPicker view and connect it File owner.
Please check below link for more detail
http://www.techotopia.com/index.php/An_iOS_5_iPhone_UIPickerView_Example
http://iosmadesimple.blogspot.in/2012/09/uipickerview-tutorial.html (More helpful)
http://www.developersalmanac.com/uipickerview-tutorial/
[countrySelector setDelegate:self];
[countrySelector setDataSource:self];
//Use this code in Viewdidload method
Add UIPickerViewDataSource and UIPickerViewDelegate in your interface file.
In viewDidLoad:
self.countrySelector.delegate = self;
self.countrySelector.dataSource = self;
You can set the delegate and dataSource directly from the xib file. But don't forget to mention them in the interface file.
-(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view{
UILabel *lblRow = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, [pickerView bounds].size.width, 44.0f)];
[lblRow setTextAlignment:NSTextAlignmentCenter];
[lblRow setTextColor: [UIColor strawberryColor]];
[lblRow setText:self.colorArray[row]];
[lblRow setFont:[UIFont fontWithName:#"Avenir-Medium" size:18]];
[lblRow setBackgroundColor:[UIColor clearColor]];
return lblRow;
}
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];
I have a problem with my UIPickerView.
I have 3 values in it EU AP and NA.
When I start the app EU seems to be selected but when I make a NSLog(#"%#", [regions objectAtIndex:row]); I only get back (null),
now when I touch the UIPickerView the EU value is selected and I get "EU" back from a NSLog.
My question is:
How can I define a default value which is selected (not only the label) when the user only starts the app and touches nothing.
Edit: Here is my code to get the selected item:
#pragma mark -
#pragma mark PickerView DataSource
- (NSInteger)numberOfComponentsInPickerView:
(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component
{
return [regions count];
}
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
return [regions objectAtIndex:row];
}
#pragma mark -
#pragma mark PickerView Delegate
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row
inComponent:(NSInteger)component
{
selectedRegion = [[NSString alloc] initWithFormat:
#"%#", [regions objectAtIndex:row]];
NSLog(#"%#", selectedRegion);
}
TL:DR version:
//Objective-C
[self.picker selectRow:2 inComponent:0 animated:YES];
//Swift
picker.selectRow(2, inComponent:0, animated:true)
Either you didn't set your picker to select the row (which you say you seem to have done but anyhow):
- (void)selectRow:(NSInteger)row inComponent:(NSInteger)component animated:(BOOL)animated
OR you didn't use the the following method to get the selected item from your picker
- (NSInteger)selectedRowInComponent:(NSInteger)component
This will get the selected row as Integer from your picker and do as you please with it.
This should do the trick for yah. Good luck.
Anyhow read the ref:
https://developer.apple.com/documentation/uikit/uipickerview
EDIT:
An example of manually setting and getting of a selected row in a UIPickerView:
the .h file:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIPickerViewDelegate, UIPickerViewDataSource>
{
UIPickerView *picker;
NSMutableArray *source;
}
#property (nonatomic,retain) UIPickerView *picker;
#property (nonatomic,retain) NSMutableArray *source;
-(void)pressed;
#end
the .m file:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize picker;
#synthesize source;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.view.backgroundColor = [UIColor yellowColor];
self.source = [[NSMutableArray alloc] initWithObjects:#"EU", #"USA", #"ASIA", nil];
UIButton *pressme = [[UIButton alloc] initWithFrame:CGRectMake(20, 20, 280, 80)];
[pressme setTitle:#"Press me!!!" forState:UIControlStateNormal];
pressme.backgroundColor = [UIColor lightGrayColor];
[pressme addTarget:self action:#selector(pressed) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:pressme];
self.picker = [[UIPickerView alloc] initWithFrame:CGRectMake(20, 110, 280, 300)];
self.picker.delegate = self;
self.picker.dataSource = self;
[self.view addSubview:self.picker];
//This is how you manually SET(!!) a selection!
[self.picker selectRow:2 inComponent:0 animated:YES];
}
//logs the current selection of the picker manually
-(void)pressed
{
//This is how you manually GET(!!) a selection
int row = [self.picker selectedRowInComponent:0];
NSLog(#"%#", [source objectAtIndex:row]);
}
- (NSInteger)numberOfComponentsInPickerView:
(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component
{
return [source count];
}
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
return [source objectAtIndex:row];
}
#pragma mark -
#pragma mark PickerView Delegate
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row
inComponent:(NSInteger)component
{
// NSLog(#"%#", [source objectAtIndex:row]);
}
#end
EDIT for Swift solution (Source: Dan Beaulieu's answer)
Define an Outlet:
#IBOutlet weak var pickerView: UIPickerView! // for example
Then in your viewWillAppear or your viewDidLoad, for example, you can use the following:
pickerView.selectRow(rowMin, inComponent: 0, animated: true)
pickerView.selectRow(rowSec, inComponent: 1, animated: true)
If you inspect the Swift 2.0 framework you'll see .selectRow defined as:
func selectRow(row: Int, inComponent component: Int, animated: Bool)
option clicking .selectRow in Xcode displays the following:
This is How to set a default Value of a UIPickerView
[self.picker selectRow:4 inComponent:0 animated:YES];
Swift solution:
Define an Outlet:
#IBOutlet weak var pickerView: UIPickerView! // for example
Then in your viewWillAppear or your viewDidLoad, for example, you can use the following:
pickerView.selectRow(rowMin, inComponent: 0, animated: true)
pickerView.selectRow(rowSec, inComponent: 1, animated: true)
If you inspect the Swift 2.0 framework you'll see .selectRow defined as:
func selectRow(row: Int, inComponent component: Int, animated: Bool)
option clicking .selectRow in Xcode displays the following:
I too had this problem. But apparently there is an issue of the order of method calls. You must call:
[self.picker selectRow:2 inComponent:0 animated:YES];
after calling
[self.view addSubview:self.picker];
You have to send
- (void)selectRow:(NSInteger)row inComponent:(NSInteger)component animated:(BOOL)animated
to the picker view before it appears. The documentation states that the method selectedRowInComp... will give -1, thus it is possible that the picker view is in a state with no selected row. It turns out to be in that state when created.
In normal case, you can do something like this in viewDidLoad method;
[_picker selectRow:1 inComponent:0 animated:YES];
In my case, I'd like to fetch data from api server and display them onto UIPickerView then I want the picker to select the first item by default.
The UIPickerView will look like it selected the first item after it was created, but when you try to get the selected index by using selectedRowInComponent, you will get NSNull.
That's because it detected nothing changed by the user (select 0 from 0 ).
Following is my solution (in viewWillAppear, after I fetched the data)
[_picker selectRow:1 inComponent:0 animated:NO];
[_picker selectRow:0 inComponent:0 animated:NO];
Its a bit dirty, but dont worry, the UI rendering in iOS is very fast ;)
For example: you populated your UIPickerView with array values, then you wanted
to select a certain array value in the first load of pickerView like "Arizona".
Note that the word "Arizona" is at index 2. This how to do it :) Enjoy coding.
NSArray *countryArray =[NSArray arrayWithObjects:#"Alabama",#"Alaska",#"Arizona",#"Arkansas", nil];
UIPickerView *countryPicker=[[UIPickerView alloc]initWithFrame:self.view.bounds];
countryPicker.delegate=self;
countryPicker.dataSource=self;
[countryPicker selectRow:2 inComponent:0 animated:YES];
[self.view addSubview:countryPicker];
In case someone is still looking answer to this old question in Swift, here is what worked for me. None of the above answers worked as I had to select the first row in viewDidLoad.
self.pickerView.delegate?.pickerView?(self.pickerView, didSelectRow: 0, inComponent: 0)
Hope this helps.