How do I add rows to UIPickerView from UIAlertController - iphone

I have a UIPickerView that gets its data from an array that is defined in
friends = [NSArray arrayWithObjects: #"jim", #"joe", #"anne", nil];
I have a button under the picker that is supposed to add new friends to the picker.
When the button is pressed a UIAlertController pops up and the user can enter the new friends name. I can save the text as a string but I can't add it to the array. I've also tried using NSMutableArray's.
I'm new to this so all input would be great. I've looked at similar questions for help but nothing has worked.
Thanks!

Ok so I will try to explain this:
You declare a NSMutbleArray, you can't expect to use a NSArray because is not mutable, and you need to modify the content.
NSMutableArray *array;
UIAlertController * view;
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSArray* friends = [NSArray arrayWithObjects: #"jim", #"joe", #"anne", nil];
array = [NSMutableArray arrayWithArray:friends];
// I added a UIPickerView in the StoryBoard, connected it to a property and the delegates and datasources.
self.pickerView.delegate = self;
}
Then you declare dataSource of UIPickerView:
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}
// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
return array.count;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
return array[row];
}
So, then you present your UIAlertController, in this case I will dismiss it in the Return of the TextView.
//This is an action connected to the button which will present the ActionController
- (IBAction)addFriend:(id)sender {
view = [UIAlertController alertControllerWithTitle:#"Add Friend" message:#"Write the friend to add"preferredStyle:UIAlertControllerStyleAlert];
[view addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.placeholder = #"Friend";
textField.delegate = self;
textField.tag = 01;
}];
[self presentViewController:view animated:YES completion:nil];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
if(textField.tag == 01){
[array insertObject:textField.text atIndex:array.count];
[view dismissViewControllerAnimated:YES completion:^{
[self.pickerView reloadAllComponents];
}];
return YES;
}
return YES;
}
This is more or less what you can do, I was the most specific I could be because you said you are a begginer.
Hope it Helps.

Related

Obj-C globally use NSArray

I have a ViewController that prompts the FBFriendPickerViewController in which I, at selection, am returned with an NSArray containing the selection. Now I want to prompt and show a new ViewController using this selection information. I am new to Objective C, but I guess the solution is pretty simple. Here is my proposal:
ViewController2.h
- (id)initWithStyle:(UITableViewStyle)style andSelection:(NSArray *)selection;
#property (strong, nonatomic) NSArray *selectedParticipants;
ViewController2.m
- (id)initWithStyle:(UITableViewStyle)style andSelection:(NSArray *)selection {
self = [super initWithStyle:style];
if (self) {
self.title = NSLocalizedString(#"Split Bill", nil);
self.tableView.backgroundColor = [UIColor wuffBackgroundColor];
self.selectedParticipants = selection;
}
return self;
}
- (void)setSelectedParticipants:(NSArray *)selectedParticipants {
NSLog(#"setSelectedParticipants (%d)", [selectedParticipants count]);
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"%d rowsInSection", [self.selectedParticipants count]);
return [self.selectedParticipants count];
}
ViewController1.m
- (void)actionSheet:(UIActionSheet *)actionSheet willDismissWithButtonIndex:(NSInteger)buttonIndex {
if (buttonIndex == 2) {
[[self friendPickerController] presentModallyFromViewController:self animated:YES handler:^(FBViewController *sender, BOOL donePressed) {
if (donePressed) {
ViewController2 *vc = [[ViewController2 alloc] initWithStyle:UITableViewStyleGrouped
andSelection:[self.friendPickerController selection]];
[self.navigationController pushViewController:vc animated:YES];
}
//[[self friendPickerController] clearSelection];
}
];
}
}
It seems, however, that the first setSelectedParticipants-log returns the correct amount of selected friends, but the numberOfRowsInSection-log returns 0.
Why is this?
Thanks in advance!
The problem here is in your setter:
- (void)setSelectedParticipants:(NSArray *)selectedParticipants {
NSLog(#"setSelectedParticipants (%d)", [selectedParticipants count]);
}
You will notice that you never actually set the value for the instance variable backing the property, in this case, the default is _selectedParticipants. So, to fix, simply add the following line to your setter:
_selectedParticipants = selectedParticipants;
And you should be good to go.
Remove this function from your code
- (void)setSelectedParticipants:(NSArray *)selectedParticipants {
NSLog(#"setSelectedParticipants (%d)", [selectedParticipants count]);
}
You are already set the selectedParticipants in init method

UIPickerview Multiple TextFields Xcode

I'm looking for a way to use a single UIPickerview for two different textfields. I'd like to have the pickerview popup when each textfield is selected. After the user selects their item, the item will populate the specific text field. The picker would have to populate based on the textfield chosen.
I've read this:
How to use one UIPickerView for multiple textfields in one view?
and this:
How to use UIPickerView to populate different textfields in one view?
and this:
Multiple sources for UIPickerView on textfield editing
However, none gives a complete solution.
I'm very new at Xcode so I'd like a solution that includes steps to set the storyboard also.
I appreciate any help as i've researched this for weeks.
EDIT: HERE IS MY CODE:
.h:
#import <UIKit/UIKit.h>
#interface klViewController : UIViewController <UIPickerViewDelegate, UIPickerViewDataSource> {
IBOutlet UITextField *textField1;
IBOutlet UITextField *textField2;
NSMutableArray *pickerArray1;
NSMutableArray *pickerArray2;
UIPickerView *pickerView;
}
#property(nonatomic,retain) IBOutlet UITextField *textField1;
#property(nonatomic,retain) IBOutlet UITextField *textField2;
#property(nonatomic,retain) IBOutlet UIPickerView *pickerView;
#end
.m:
#import "klViewController.h"
#interface klViewController ()
#end
#implementation klViewController
#synthesize pickerView;
#synthesize textField1;
#synthesize textField2;
int variabla;
-(void)textFieldDidBeginEditing:(UITextField *)textField{
[pickerView setHidden:YES];
if (textField1.editing == YES) {
[textField1 resignFirstResponder];
[pickerView setHidden:NO];
variabla = 1;
}else if (textField2.editing == YES) {
[textField2 resignFirstResponder];
[pickerView setHidden:NO];
variabla = 2;
}
NSLog(#"variabla %d",variabla);
[pickerView reloadAllComponents];
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
{
if (variabla == 1) {
return [pickerArray1 count];
}else if (variabla == 2) {
return [pickerArray2 count];
}else {
return 0;
}
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
{
if (variabla == 1) {
return [pickerArray1 objectAtIndex:row];
}else if (variabla == 2) {
return [pickerArray2 objectAtIndex:row];
}else {
return 0;
}
}
- (void)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
}
- (void)viewDidLoad {
[super viewDidLoad];
[pickerView setHidden:YES];
pickerArray1 = [[NSMutableArray alloc] initWithObjects:#"0", #"1", #"2", nil];
pickerArray2 = [[NSMutableArray alloc] initWithObjects:#"3", #"4", #"5", nil];
}
#end
HERE IS A SCREEN SHOT OF MY STORYBOARD:
STATUS UPDATE:
When I run the program:
1) the pickerview is hidden.
2) when I select a textfield, the picker view appears and populates correctly depending on the textfield selected.
PROBLEMS:
1) Picker doesn't go away when click outside of the textfield.
2) Textfields don't populated when a row in the Picker is selected.
Hope this provides more insight.
1) Picker doesn't go away when click outside of the textfield.
You have no code that attempts to make the picker go away when that happens. Try adding a simple tap gesture recognizer to the view. Add a line to viewDidLoad like:
[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(backgroundTap:)]];
Then implement the function simply like:
-(void)backgroundTap:(UITapGestureRecognizer *)tapGR{
self.pickerView.hidden = YES;
// And maybe..
variabla = 0;
}
Since you are making the picker appear and disappear using the hidden property this will work very simply. There are other more sophisticated ways to do this which I hope you explore. Generally the picker is set as the textfield's inputView property; that is worth investigating.
2) Textfields don't populated when a row in the Picker is selected.
You haven't handled the picker's pickerView:didSelectRow:inComponent: delegate method. That's the method that gets called when the picker stops turning and lands on an item. Don't assume that this is the item the user selected it will be called multiple times.
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
NSString *text = [self pickerView:pickerView titleForRow:row forComponent:component];
UITextField *current = nil;
if (variabla == 1) current = self.textField1;
else if (variabla == 2) current = self.textField2;
current.text = text;
}
That should get your implementation working. One more thing though variabla is an instance variable and should be declared in curly braces immediately following the #interface or #implementation line.
#implementation klViewController {
int variabla;
}
#synt....
Give the Tag of two Different textfield for identify which textfield you select and everything is ok you just need to change below method.
Hope This Work
-(void)textFieldDidBeginEditing:(UITextField *)textField {
if ([textField viewWithTag:100]) {
[textField resignFirstResponder];
[self.View1 setHidden:NO];
variable=1;
}
else if ([textField viewWithTag:101]) {
[textField resignFirstResponder];
[self.View1 setHidden:NO];
variable=2;
}
[_Picker_view reloadAllComponents];
}
Thanks :)
Make sure you have declared the Picker View object in the header file.
In the header file, import the UITextFieldDelegate protocol:
#interface MyView:UIViewController < UITextFieldDelegate>
In IB, set a tag for each text field you have.
In the *.m file, implement the textFieldShouldBeginEditing method, update the PickerView array Data Source and Reload all the picker view components.
-(BOOL) textFieldShouldBeginEditing:(UITextField *)textField {
if (textField.tag == 1) {
itemsArray = [[NSArray alloc] arrayWithObjects:#"A", #"B"];
}
if (textField.tag == 2) {
itemsArray = [[NSArray alloc] arrayWithObjects:#"Green", #"Yellow"];
}
[myPickerView reloadAllComponents];
}
Make sure you import the UIPickerViewDelegate and UIPickerViewDataSource in the header file.
You can use the same picker view for as many text fields as you want, to change the content of the picker view according to the selected text field you need to replace the data source of the picker view with different items whenever a text field is being selected and then reload the picker view components.
Well my friend, I'm afraid it's a little bit to complicated to explain here.
You can set object's tag value in the IB properties menu.
Once you dragged a PickerView into your view and it's selected, you can change the tag attribute in the Object Properties menu (on the side).
I think you should look for tutorials that will show you how to setup a simple picker view, or table view (they work very similar to one another) and that will give you much more information on how to do what you want to do. In a nutshell, every Picker View takes information from a Data Source, you can create an array that contains some strings and have the picker view load each item in the array as a row. I have a small website with some beginners information, check it out.
http://i-tutor.weebly.com/index.html
In .h
#interface TQViewController : UIViewController<UIPickerViewDelegate>
{
UITextField *textfield;
UIPickerView *Picker1;
NSArray *Array1,*Array2;
}
end
and in .m
- (void)viewDidLoad
{
[super viewDidLoad];
//TextField
textfield=[[UITextField alloc]initWithFrame:CGRectMake(5,5,310,40)];
textfield.borderStyle = UITextBorderStyleRoundedRect;
textfield.backgroundColor=[UIColor whiteColor];
textfield.textAlignment = UITextAlignmentCenter;
textfield.placeholder = #"<enter amount>";
[self.view addSubview:textfield];
textfield1=[[UITextField alloc]initWithFrame:CGRectMake(5,100,310,40)];
textfield1.borderStyle = UITextBorderStyleRoundedRect;
textfield1.backgroundColor=[UIColor whiteColor];
textfield1.textAlignment = UITextAlignmentCenter;
textfield1.placeholder = #"<enter amount>";
[self.view addSubview:textfield1];
// PickerView1
Array1=[[NSArray alloc]initWithObjects:#"USD",#"INR",#"EUR", nil];
Picker1=[[UIPickerView alloc]initWithFrame:CGRectMake(0, 50, 320,10)];
Picker1.delegate=self;
Picker1.tag=PICKER1_TAG;
Picker1.showsSelectionIndicator=YES;
[self.view addSubview:Picker1];
Array2=[[NSArray alloc]initWithObjects:#"USD",#"INR",#"EUR", nil];
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if([textfield becomeFirstResponder])
return [Array1 count];
if([textfield1 becomeFirstResponder])
return [Array2 count];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
NSString *title;
if([textfield becomeFirstResponder])
{
title=[Array1 objectAtIndex:row];
return title;
}
([textfield1 becomeFirstResponder])
{
title=[Array2 objectAtIndex:row];
return title;
}
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if([textfield becomeFirstResponder])
{
//your code
}
([textfield1 becomeFirstResponder])
{
//your code
}
}

Trouble with the UITextField inputview property pulling up a custom UIPickerView

I have been having trouble pulling up a custom UIPickerView from the textfield's inputview property. I have been working on this for awhile, did some research, and tried to put together a separate project based on Apple's UICatalog example.
However, whenever I tap inside the textfield all I get is a black screen that pops up in place of the picker view. Im sure I've overlooked something but I have been looking for days any help would be appreciated.
Keep in mind this was my test project to see if I could add this functionality to my other app and that a lot of the code I tried to copy from the UICatalog app. Sorry if anything doesn't make sense and please feel free to ask any questions you may have. Thank you.
// ViewController.h
// TestPicker
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UITextFieldDelegate,UIPickerViewDelegate,UIPickerViewDataSource>{
UIPickerView *picker;
//The picker view the textfield responds to.
IBOutlet UITextField *myText;
//The textfield which has the input view of a picker.
NSArray *testArray;
//The array which values are loaded into the picker.
}
#end
// ViewController.m
// TestPicker
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
picker.delegate=self;
picker.dataSource=self;
myText.delegate=self;
[self createPicker];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
myText = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
else {
return YES;
}
}
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
picker = [[UIPickerView alloc] initWithFrame:CGRectZero];
myText.inputView=picker;
return YES;
}
-(void)textFieldDidBeginEditing:(UITextField *)textField{
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
NSString *returnStr = #"";
if (pickerView == picker)
{
if (component == 0)
{
returnStr = [testArray objectAtIndex:row];
}
else
{
returnStr = [[NSNumber numberWithInt:row] stringValue];
}
}
return returnStr;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [testArray count];
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (void)createPicker
{
testArray = [NSArray arrayWithObjects:
#"John Appleseed", #"Chris Armstrong", #"Serena Auroux",
#"Susan Bean", #"Luis Becerra", #"Kate Bell", #"Alain Briere",
nil];
picker = [[UIPickerView alloc] initWithFrame:CGRectZero];
picker.showsSelectionIndicator = YES; // note this is default to NO
picker.delegate = self;
picker.dataSource = self;
}
#end
The problem is in this method:
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
picker = [[UIPickerView alloc] initWithFrame:CGRectZero];
myText.inputView=picker;
return YES;
}
You already created picker in your createPicker method, called from viewDidLoad, so this creates another instance (this instance won't have the delegate or data source set to self, since these were set on the first instance you created). If you just delete the first line of this method, it should work.
Two other comments on your code. The first 2 lines in the viewDidLoad method aren't doing anything since you haven't created picker yet -- they should be deleted. You also need to implement the pickerView:didSelectRow:inComponent: method in order to get the selected value of your picker into the text field.

picker not loading data

I have a detail view with several textfields, next to one of them i have a button a user can click to pop up a single component picker. the picker is hidden till the user clicks the button. just to make sure that the basics work, I have a simple array assignd to the pickerdata. the button to show the picker works but the data doesn't show up, here is the code
- (IBAction)ButtonPressed
{
NSArray *array = [[NSArray alloc] initWithObjects:#"data", #"data 1", nil];
self.pickerData = array;
vPicker.hidden = NO;
selectButton.hidden = NO;
}
#pragma mark -
#pragma mark Picker Data Source Methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [pickerData count];
}
#pragma mark Picker Delegate Methods
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
return [pickerData objectAtIndex:row];
}
Include UIPickerview datasource and delegate in the interface of your class..then set vpicker.datasource = self and vpicker.delegate= self;

Default Picker Value iphone

Is there a way to set a default value for a picker? I save the last selected row from all the pickers and I want to be able to have the pickers load those saved rows at start up. As of now I have found this code:
[settingsPagePicker selectRow:3 inComponent:0 animated:YES];
It works but only when the user taps the picker. I need it to work when the app is first loaded. If I put this code at viewDidLoad the app will crash.
Anyone know where the proper place to put this in my code to make it work?
Thank you for your time!
Have you checked your data source for the settingsPagePicker before calling -selectRow:inComponent:animated to make sure there is data available at that index (3 in your sample code)?
How are you loading your data for your data source? You can initialize your data source in viewDidLoad first and then call selectRow once you know there is data available.
UPDATE: Here is what your code should look like or something like it:
- (void)viewDidLoad
{
[super viewDidLoad];
pickerDataSource = [[NSMutableArray alloc] init];
[pickerDataSource addObject:#"Item 01"];
[pickerDataSource addObject:#"Item 02"];
[pickerDataSource addObject:#"Item 03"];
[pickerDataSource addObject:#"Item 04"];
// Might want to move this to -viewWillAppear:animated
[settingsPagePicker selectRow:3 inComponent:0 animated:YES];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (pickerView == settingsPagePicker)
{
return [pickerDataSource objectAtIndex:row];
}
return #"";
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if (pickerView == settingsPagePicker)
{
return [pickerDataSource count];
}
return 0;
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView
{
return 1;
}
Here some methods from my class.
- (void)viewDidLoad {
[super viewDidLoad];
currentNumbersOfComponents = 1;
//[picker selectRow:2 inComponent:0 animated:NO];
}
- (void) viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[picker selectRow:2 inComponent:0 animated:YES];
}
#pragma mark picker view data source methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return currentNumbersOfComponents;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
return 5;
}
picker.dataSource is self