Let me try to explain what I have on view and what's I'm trying to accomplish. I have a viewcontroller with two UIPickerView's in it. Each UIPickerView is connected via IFB. Everything works great but I'm trying to reload the data on one picker depending on which selection of another picker.
.m file
- (void)viewDidLoad
{
[super viewDidLoad];
pickerViewArray = [[NSMutableArray alloc] init];
[pickerViewArray addObject:#"Name 1"];
[pickerViewArray addObject:#"Name 2"];
[pickerViewArray addObject:#"Name 3"];
[pickerViewArray addObject:#"Name 4"];
[pickerViewArray addObject:#"Name 5"];
pickerViewArray2 = [[NSMutableArray alloc] init];
[pickerViewArray2 addObject:#"Phone 1"];
[pickerViewArray2 addObject:#"Phone 2"];
[pickerViewArray2 addObject:#"Phone 3"];
[pickerViewArray2 addObject:#"Phone 4"];
[pickerViewArray2 addObject:#"Phone 5"];
}
}
- (void)pickerView:(UIPickerView *)aPickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
if([[pickerViewArray2 objectAtIndex:row] isEqual:#"Phone 2"]){
[picker2 reload];
}
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)aPickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)aPickerView numberOfRowsInComponent:(NSInteger)component {
return [pickerViewArray count];
}
- (NSString *)pickerView:(UIPickerView *)aPickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [pickerViewArray objectAtIndex:row];
}
Edit: to fix the problem I was having just add the array to each aPickerView i.e. titleForRow etc.
The reload method does just that - reloads the existing data. You need to move the logic that you have in viewDidLoad into titleForRow and numberOfRowsInComponent so that once the first picker has been actioned, the correct data can be returned. At the moment you load something different into pickerViewArray2 only at viewDidLoad, and that won't be re-run by your reload method.
Related
I am trying to develop a part of my application where i can create two UIPickerView one depends on the other. Here is my code below as i have two UIpickerview (pickerView1 and pickerView2). when I change the selects of pickerView1 one ,the data must be changed in pickerView2.
the problem is when I change the select of pickerView1 every time i have old select. for example
if i select the second value of pickerView1 and before i select the first value of pickerView1, then i have on pickerView2 the value of first select and not for second value.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
arrayNo = [[NSMutableArray alloc] init];
[arrayNo addObject:#" 100 "];
[arrayNo addObject:#" 200 "];
arrayNo2= [[NSMutableArray alloc] init];
[arrayNo2 addObject:#" a "];
[arrayNo2 addObject:#" e "];
[arrayNo2 addObject:#" c "];
[arrayNo2 addObject:#" v "];
[arrayNo2 addObject:#" g "];
arrayNo3 = [[NSMutableArray alloc] init];
[arrayNo3 addObject:#""];
NSArray *keys = [NSArray arrayWithObjects:#" ",#"key1", #"key2", nil];
NSArray *objects = [NSArray arrayWithObjects:arrayNo3,arrayNo, arrayNo2, nil];
_dataOfProfile = [NSDictionary dictionaryWithObjects:objects
forKeys:keys];
pickerView1.tag = 1;
pickerView2.tag = 2;
[pickerView1 selectRow:0 inComponent:0 animated:NO];
[pickerView2 selectRow:0 inComponent:0 animated:NO];
selectedKey =[keys objectAtIndex:0];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
// 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
{
if (pickerView.tag == 1)
{
NSArray *key = [_dataOfProfile allKeys];
return [key count];
}
else
{
if (pickerView.tag == 2)
{
NSArray *keys =[_dataOfProfile objectForKey:selectedKey];
return [keys count];
}
}
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (pickerView.tag == 1)
{
NSArray *keys =[_dataOfProfile allKeys];
return [keys objectAtIndex:row];
}
else
{
if (pickerView.tag == 2)
{
return [[_dataOfProfile objectForKey:selectedKey] objectAtIndex:row];
}
}
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (pickerView.tag == 1)
{
//Means a value just changed on your picker 2!, update datasource for your second picker
[pickerView2 reloadComponent:0];
selectedKey= [[_dataOfProfile allKeys] objectAtIndex:row];
}
}
Try like following -
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (pickerView.tag == 1)
{
//Means a value just changed on your picker 2!, update datasource for your second picker
//write this line before loading the picker.....
selectedKey= [[_dataOfProfile allKeys] objectAtIndex:row];
[pickerView2 reloadComponent:0];
}
}
I'm using the Utility Application Template with Core Data. In the flipside view, user can add items and these items brand and model feed a UIPickerView on the main view.
When the user adds an item, unless she or he closes the app this added item does not appear in the picker row titles.
How can I load this title without closing the app?
Thanks
Edit to add code:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//retrieving data from iGear.xcdatamodeld
iGearAppDelegate *iGearDelegate = [[UIApplication sharedApplication]delegate];
NSManagedObjectContext *context = [iGearDelegate managedObjectContext];
NSError *error;
if (managedObjectContext !=nil) {
if ([managedObjectContext hasChanges] && [managedObjectContext save:&error]) {
//NSLog(#"Retrieving: unresolved error %#, %#",error, [error userInfo]);
abort();
}
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Cogset" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
//#pragma mark UIPickerView
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent: (NSInteger)component
{
return [fetchedObjects count];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (component == 0)
{
cogset = [fetchedObjects objectAtIndex:row];
return [NSString stringWithFormat:#"%# %#",cogset.brand,cogset.model];
}
return #"";
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
cassette = [fetchedObjects objectAtIndex:[_chooseCogsetPickerView selectedRowInComponent:0]];
}
You should implement a UIPickerViewDelegate for your UIPickerView.
Then, use this delegate function to populate your picker view:
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component ]
{
return someValue;
}
I can try to help you more specifically if you post some actual code with what's currently happening.
I am trying to make a calculating app that consists of a 2-column picker. The left side of the picker are data values and the data values are being pulled from a plist with the price of each item. The other side of the picker is a string going from 1 to 64.
I'm trying to figure out how to take the string values of both parts of the picker and convert them into an int (so they can be multiplied and printed out)
Here's my code (in its entirety)
#pragma mark - View lifecycle
- (void)viewDidLoad
{
NSBundle *bundle = [NSBundle mainBundle];
NSString *plistPath =[bundle pathForResource:#"worthList" ofType:#"plist"];
NSDictionary *dictionary = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
self.dataValues = dictionary;
[dictionary release];
NSArray *components = [self.dataValues allKeys];
NSArray *sorted = [components sortedArrayUsingSelector:#selector(compare:)];
self.values = sorted;
NSMutableArray *number =[[NSMutableArray alloc] init];
for(int x = 1; x < 65; x++)
{
NSString * numberString = [[NSString alloc] initWithFormat:#"%d",x];
[number addObject:numberString];
}
self.quantity = number;
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)viewDidUnload
{
self.doublePicker = nil;
self.dataValues = nil;
self.values = nil;
self.quantity = nil;
[self setDoublePicker:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (IBAction)calculateItem:(id)sender
{
NSString *message = [[NSString alloc] initWithFormat:#""];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Thank you" message:message delegate:nil cancelButtonTitle:#"Okay" otherButtonTitles: nil];
[alert show];
[alert release];
[message release];
}
#pragma mark -
#pragma Picker data source methods
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 2;
}
-(NSInteger)pickerView:(UIPickerView *) pickerView numberOfRowsInComponent:(NSInteger)component
{
if (component == kValueComponent)
{
return [self.values count];
}
return [self.quantity count];
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent: (NSInteger)component
{
if (component == kValueComponent)
{
return [self.values objectAtIndex:row];
}
return [self.quantity objectAtIndex:row];
}
#end
Try this to convert your data string into an int and then do the calculation:
int = [yourString intValue];
Try this:
NSString *str=[NSString stringWithFormat:#"%#",[pickerArr objectAtIndex:row]];
int test=[str intValue];
HERE MINUTES AND SECONDS ARE ARRAY.
Delegate method of a picker.
You can use other delegate methods also.
Seconds and minutes are the array which loads the picker in your case use array which is feeded with plist.
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
switch (component) {
case 0:
minuteTime =[minutes objectAtIndex:row] intValue];
break;
case 1:
secondTime = [[seconds objectAtIndex:row] intValue];
break;
}
}
You can also use this method to distinguish strings further.
NSArray *greenTime = [yourstring componentsSeparatedByString:#":"];
NSLog(#"Green Time : %#\nFirst : %#\nSecond : %#",greenTime,[greenTime objectAtIndex:0],[greenTime objectAtIndex:1]);
I am working on a view that selects an image (chart) based on user input through a dependent picker which uses a plist file that contains three arrays containing about 40 strings each.
About 50% of the time when I run the app, it just shuts down immediately, but the other times that it does run, it will work fine until I start scrolling through the picker at which point it crashes after about 4 seconds. It also wont show one of the array names on the left component.
I tried running the app with the analyzer to check on a memory leak, but it wont run at all if I am using analyzer in memory leak mode. The code is almost straight out of a book.
Here is the relevant code:
-(void) viewDidLoad {
[super viewDidLoad];
UIImageView *tempImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"US High Index.jpg"]];
self.imageView = tempImageView;
NSString *string = #"US High Index";
self.chartNameLabel.text = string;
[string release];
[tempImageView release];
scrollView.contentSize = CGSizeMake(imageView.frame.size.width , imageView.frame.size.height);
scrollView.maximumZoomScale = 4.0;
scrollView.minimumZoomScale = .05;
scrollView.clipsToBounds = YES;
scrollView.delegate = self;
[scrollView addSubview:imageView];
NSBundle *bundle = [NSBundle mainBundle];
NSString *plistPath = [bundle pathForResource:#"ChartTypes" ofType:#"plist"];
NSDictionary *dictionary = [[NSDictionary alloc]initWithContentsOfFile:plistPath];
self.chartsDictionary = dictionary;
NSArray *components = [self.chartsDictionary allKeys];
self.chartTypes = components;
NSString *selectedChartType = [self.chartTypes objectAtIndex:0];
NSArray *array = [chartsDictionary objectForKey:selectedChartType];
self.charts = array;
[dictionary release];
[array release];
[selectedChartType release];
[plistPath release];
[bundle release];
}
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 2;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component {
if (component == kChartTypeComponent )
return [self.chartTypes count];
return [self.charts count];
}
#pragma mark Picker delegate methods
-(NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component {
if (component == kChartTypeComponent )
return [self.chartTypes objectAtIndex:row];
return [self.charts objectAtIndex:row];
}
-(void)pickerView:(UIPickerView *)pickerView
didSelectRow: (NSInteger)row
inComponent:(NSInteger)component {
if (component == kChartTypeComponent ) {
NSString *selectedChartType = [self.chartTypes objectAtIndex:row];
NSArray *array = [chartsDictionary objectForKey:selectedChartType];
self.charts = array;
[picker selectRow: 0 inComponent:kChartComponent animated: YES];
[picker reloadComponent:kChartComponent];
}
}
I think you don't have to call
[array release];
[selectedChartType release];
in your viewDidLoad method, because both objects are autoreleased. Maybe that could cause the crash.
I have written a UIPicker which is populated from a .plist. This part works fine.
What I don't know how do is once the row has been selected is to display that underlying data in another UIView.
The code in my .m file is:
#import "airlinePickerViewController.h"
#implementation airlinePickerViewController
#synthesize picker;
#synthesize airlines;
#synthesize airline;
#synthesize teleno;
- (IBAction)butonPressed:(id)sender
{
NSInteger airRow = [picker selectedRowInComponent:kAirlineComponent];
NSInteger telRow = [picker selectedRowInComponent:kTelenoComponent];
NSString *air = [self.airline objectAtIndex:airRow];
NSString *tel = [self.teleno objectAtIndex:telRow];
NSString *title = [[NSString alloc] initWithFormat:#"You selected %#.", tel];
NSString *message = [[NSString alloc] initWithFormat:#"%# is in %#", tel, air];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
[title release];
[message release];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
// Initialization code
}
return self;
}
- (void)viewDidLoad {
NSBundle *bundle = [NSBundle mainBundle];
NSString *plistPath = [bundle pathForResource:#"airlinedictionary" ofType:#"plist"];
NSDictionary *dictionary = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
self.airlines = dictionary;
[dictionary release];
NSArray *components = [self.airlines allKeys];
NSArray *sorted = [components sortedArrayUsingSelector:#selector(compare:)];
self.airline = sorted;
NSString *selectedAirline = [self.airline objectAtIndex:0];
NSArray *array = [airlines objectForKey:selectedAirline];
self.teleno = array;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
- (void)dealloc {
[picker release];
[airlines release];
[airline release];
[teleno release];
[super dealloc];
}
#pragma mark -
#pragma mark Picker Data Source Methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if (component == kAirlineComponent)
return [self.airline count];
return [self.teleno count];
}
#pragma mark Picker Delegate Methods
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (component == kAirlineComponent)
return [self.airline objectAtIndex:row];
return [self.teleno objectAtIndex:row];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (component == kAirlineComponent)
{
NSString *selectedAirline = [self.airline objectAtIndex:row];
NSArray *array = [airlines objectForKey:selectedAirline];
self.teleno = array;
[picker selectRow:0 inComponent:kTelenoComponent animated:YES];
[picker reloadComponent:kTelenoComponent];
}
}
#end
Can anyone help me get to grips with how to complete this task.
Many thanks
Dereck
Now a somehow general answer:
I assume you want to switch to a completely new View (not a subview) so the first thing you probably need is a Navigation Controller or TabBarController to facilitate pushing / switching to new Views. Before switching / pushing the new View you could assign the selected values as properties to that new View after initialization but before switching to the new View.