I have a UIPicker with 3 components containing numeric values, this allows the user to set the time in hh:mm:ss format. If I select the hour from the first component my UITextField looks like this: 10:(null):(null). The (null) can be removed when the user selects the appropriate mm and ss. But if the user just wants to enter 10 hours, I want the other values to be 00 instead of (null), without the user having to physically move the picker components.
Anyone have any ideas on this ?
Some code below, this question is related to the timePicker.
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if([pickerView isEqual: routePicker])
{
route.text = [[routeArray objectAtIndex:0] valueForKey:#"route_name"];
return [[routeArray objectAtIndex:row] valueForKey:#"route_name"];
}
else if([pickerView isEqual: activityPicker])
{
activity.text = [activityArray objectAtIndex:0];
return [activityArray objectAtIndex:row];
}
else if([pickerView isEqual: intensityPicker])
{
if ([intensityArray objectAtIndex:row]==#"Low")
numberIntensity=2;
else if ([intensityArray objectAtIndex:row]==#"Low-Medium")
numberIntensity=3.5;
else if ([intensityArray objectAtIndex:row]==#"Medium")
numberIntensity=5;
else if ([intensityArray objectAtIndex:row]==#"Medium-High")
numberIntensity=6.5;
else if ([intensityArray objectAtIndex:row]==#"High")
numberIntensity=8;
else numberIntensity=0;
intensity.text = [intensityArray objectAtIndex:0];
return [intensityArray objectAtIndex:row];
}
else if([pickerView isEqual: timePicker])
{
switch (component)
{
case 0:
return [hourArray objectAtIndex:row];
break;
case 1:
return [minuteArray objectAtIndex:row];
break;
case 2:
return [secondArray objectAtIndex:row];
break;
default:
return 0;
break;
}
}
else if([pickerView isEqual: distancePicker])
{
switch (component)
{
case 0:
return [distance1Array objectAtIndex:row];
break;
case 1:
return [distance2Array objectAtIndex:row];
break;
default:
return 0;
break;
}
}
else
{
return 0;
}
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if([pickerView isEqual: routePicker])
{
route.text = [[routeArray objectAtIndex:row] valueForKey:#"route_name"];
}
else if([pickerView isEqual: timePicker])
{
if (component == 0)
{
selectedHour = [hourArray objectAtIndex:row];
}
else if (component == 1)
{
selectedMinute = [minuteArray objectAtIndex:row];
}
else if (component == 2)
{
selectedSecond = [secondArray objectAtIndex:row];
}
time.text = [NSString stringWithFormat:#"%#:%#:%#", selectedHour, selectedMinute, selectedSecond];
}
else if([pickerView isEqual: distancePicker])
{
if (component == 0)
{
selectedDistance1 = [distance1Array objectAtIndex:row];
}
else if (component == 1)
{
selectedDistance2 = [minuteArray objectAtIndex:row];
}
distance.text = [NSString stringWithFormat:#"%#.%#", selectedDistance1, selectedDistance2];
}
else if([pickerView isEqual: activityPicker])
{
activity.text = [activityArray objectAtIndex:row];
}
else if([pickerView isEqual: intensityPicker])
{
intensity.text = [intensityArray objectAtIndex:row];
}
}
I think this line:
time.text = [NSString stringWithFormat:#"%#:%#:%#", selectedHour, selectedMinute, selectedSecond];
could be changed to:
time.text = [NSString stringWithFormat:#"%#:%#:%#",
(selectedHour ? selectedHour : #"00"),
(selectedMinute ? selectedMinute : #"00"),
(selectedSecond ? selectedSecond : #"00")];
This assumes that selectedHour, selectedMinute and selectedSecond are all initially nil outside of this code. I am away from my mac, so I haven't tested this.
Alternatively, you could initialize selectedHour, selectedMinute and selectedSecond to #"00".
Related
I have 2 UIPickerView right now and I want to add three more later.The code is below:
-(void)viewDidLoad{
Pos_x = 5;
Pos_y = 70;
for (i= 0; i<2; i++) {
myPickerView = [[UIPickerView alloc] init];
myPickerView.frame = CGRectMake(Pos_x,Pos_y,150,300);
myPickerView.tag = i;
myPickerView.delegate = self;
myPickerView.showsSelectionIndicator = YES;
[self.view addSubview:myPickerView];
if (i==0) {
// Init the data array.
Array_1 = [[NSMutableArray alloc] init];
// Add some data for demo purposes.
[Array_1 addObject:#"One"];
[Array_1 addObject:#"Two"];
[Array_1 addObject:#"Three"];
[Array_1 addObject:#"Four"];
[Array_1 addObject:#"Five"];
}
if (i==1) {
Array_2 = [[NSMutableArray alloc] init];
// Add some data for demo purposes.
[Array_2 addObject:#"One1"];
[Array_2 addObject:#"Two1"];
[Array_2 addObject:#"Three1"];
[Array_2 addObject:#"Four1"];
[Array_2 addObject:#"Five1"];
}
Pos_x = Pos_x + 162;
}
}
I have successfully created two UIPickerView with tag. Now the problem is adding data in UIPickerView.
I am doing like this
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
//return [Array_1 objectAtIndex: row]; // If give only this line both UIPickerView show same value.
//How to show both
//return [Array_2 objectAtIndex: row];
// I also tried this code
if(pickerView == myPickerView){
if (i==0){
}
return [Array_1 objectAtIndex: row];
}
if (i==1){
}
return [Array_2 objectAtIndex: row];
}
}
Now my question is that how to show different different data on two UIPickerView? like on pickerview.tag ==0 it will show return [Array_1 objectAtIndex: row];
And pickerview.tag ==1 it will show return [Array_2 objectAtIndex: row];?
Any idea or suggestions would be welcome.
Please check this code:
-(void)viewDidLoad{
myPickerView = [[UIPickerView alloc] init];
myPickerView.frame = CGRectMake(5,70,150,300);
//myPickerView.tag = i;
myPickerView.delegate = self;
myPickerView.showsSelectionIndicator = YES;
[self.view addSubview:myPickerView];
Array_1 = [[NSMutableArray alloc] init];
// Add some data for demo purposes.
[Array_1 addObject:#"One"];
[Array_1 addObject:#"Two"];
[Array_1 addObject:#"Three"];
[Array_1 addObject:#"Four"];
[Array_1 addObject:#"Five"];
[Array_1 addObject:#"Six"];
myPickerView_2nd = [[UIPickerView alloc] init];
myPickerView_2nd.frame = CGRectMake(167,70,150,300);
//myPickerView_2nd.tag = i;
myPickerView_2nd.delegate = self;
myPickerView_2nd.showsSelectionIndicator = YES;
[self.view addSubview:myPickerView_2nd];
Array_2 = [[NSMutableArray alloc] init];
// Add some data for demo purposes.
[Array_2 addObject:#"One1"];
[Array_2 addObject:#"Two1"];
[Array_2 addObject:#"Three1"];
[Array_2 addObject:#"Four1"];
[Array_2 addObject:#"Five1"];
[Array_2 addObject:#"Six1"];
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
if([pickerView isEqual: myPickerView]){
// return the appropriate number of components, for instance
return 1;
}
if([pickerView isEqual: myPickerView_2nd]){
// return the appropriate number of components, for instance
return 1;
}
else
return 0;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent: (NSInteger)component {
if ( pickerView == myPickerView) // this is otherPickerview
{
return [Array_1 count];
}
if ( pickerView == myPickerView_2nd){
return [Array_2 count];
}
else{
NSUInteger numRows = 5;
return numRows;}
}
Hope This will Help You...
You can use an Array or Dictionary to store the content arrays and get them with picker's tag. E. g.
NSArray *contentArrays = [[NSArray alloc] initWithObjects:Array_1, Array_2, nil];
Then get the content array with [contentArrays objectAtIndex:pickerView.tag];
You can do so by setting tags of the pickerview:
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger) {
if(pickerView.tag == 1)
{
// do something with picker one
}
else if(pickerView.tag == 2)
{
// the other picker
}
}
Or else:
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger) {
switch(pickerView.tag){
case 1:
//do something
break;
case 2:
//do other thing
break;
default:
break;
}
}
Hope this helps..
Have a look at this as well: Multiple PickerViews in one View?
my problem is that i cant parse the tag from a xml file.
It returns a null value, im testing it by using an NSLog with %#.
If someone could point me a solution i would be very thankful.
Here is the code:
BOOL processed = NO;
if (currentText) {
// Remove newlines and whitespace from currentText
NSString *processedText = [currentText stringByRemovingNewLinesAndWhitespace];
// Process
switch (feedType) {
case FeedTypeRSS: {
// Item
if (!processed) {
if ([currentPath isEqualToString:#"/rss/channel/item/title"]) { if (processedText.length > 0) item.title = processedText; processed = YES; }
else if([currentPath isEqualToString:#"/rss/channel/item/url"]) { if (processedText.length > 0) item.image = processedText; processed = YES; }
else if([currentPath isEqualToString:#"/rss/channel/item/category"]) { if (processedText.length > 0) item.category = processedText; processed = YES; }
else if ([currentPath isEqualToString:#"/rss/channel/item/link"]) { if (processedText.length > 0) item.link = processedText; processed = YES; }
else if ([currentPath isEqualToString:#"/rss/channel/item/guid"]) { if (processedText.length > 0) item.identifier = processedText; processed = YES; }
else if ([currentPath isEqualToString:#"/rss/channel/item/description"]) { if (processedText.length > 0) item.summary = processedText; processed = YES; }
else if ([currentPath isEqualToString:#"/rss/channel/item/content:encoded"]) { if (processedText.length > 0) item.content = processedText; processed = YES; }
else if ([currentPath isEqualToString:#"/rss/channel/item/pubDate"]) { if (processedText.length > 0) item.date = [NSDate dateFromInternetDateTimeString:processedText formatHint:DateFormatHintRFC822]; processed = YES; }
else if ([currentPath isEqualToString:#"/rss/channel/item/enclosure"]) { [self createEnclosureFromAttributes:currentElementAttributes andAddToItem:item]; processed = YES; }
else if ([currentPath isEqualToString:#"/rss/channel/item/dc:date"]) { if (processedText.length > 0) item.date = [NSDate dateFromInternetDateTimeString:processedText formatHint:DateFormatHintRFC3339]; processed = YES; }
}
// Info
if (!processed && feedParseType != ParseTypeItemsOnly) {
if ([currentPath isEqualToString:#"/rss/channel/title"]) { if (processedText.length > 0) info.title = processedText; processed = YES; }
else if([currentPath isEqualToString:#"/rss/channel/item/url"]) { if (processedText.length > 0) item.image = processedText; processed = YES; }
else if([currentPath isEqualToString:#"/rss/channel/item/category"]) { if (processedText.length > 0) item.category = processedText; processed = YES; }
else if ([currentPath isEqualToString:#"/rss/channel/description"]) { if (processedText.length > 0) info.summary = processedText; processed = YES; }
else if ([currentPath isEqualToString:#"/rss/channel/link"]) { if (processedText.length > 0) info.link = processedText; processed = YES; }
}
break;
}
case FeedTypeRSS1: {
// Item
if (!processed) {
if ([currentPath isEqualToString:#"/rdf:RDF/item/title"]) { if (processedText.length > 0) item.title = processedText; processed = YES; }
else if([currentPath isEqualToString:#"/rss/channel/item/url"]) { if (processedText.length > 0) item.image = processedText; processed = YES; }
else if([currentPath isEqualToString:#"/rss/channel/item/category"]) { if (processedText.length > 0) item.category = processedText; processed = YES; }
else if ([currentPath isEqualToString:#"/rdf:RDF/item/link"]) { if (processedText.length > 0) item.link = processedText; processed = YES; }
else if ([currentPath isEqualToString:#"/rdf:RDF/item/dc:identifier"]) { if (processedText.length > 0) item.identifier = processedText; processed = YES; }
else if ([currentPath isEqualToString:#"/rdf:RDF/item/description"]) { if (processedText.length > 0) item.summary = processedText; processed = YES; }
else if ([currentPath isEqualToString:#"/rdf:RDF/item/content:encoded"]) { if (processedText.length > 0) item.content = processedText; processed = YES; }
else if ([currentPath isEqualToString:#"/rdf:RDF/item/dc:date"]) { if (processedText.length > 0) item.date = [NSDate dateFromInternetDateTimeString:processedText formatHint:DateFormatHintRFC3339]; processed = YES; }
else if ([currentPath isEqualToString:#"/rdf:RDF/item/enc:enclosure"]) { [self createEnclosureFromAttributes:currentElementAttributes andAddToItem:item]; processed = YES; }
}
call method:
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
// Configure the cell.
MWFeedItem *item = [itemsToDisplay objectAtIndex:indexPath.row];
if (item) {
NSLog(#"content = %#",item.content);//<-------------------------------------------Returns a NULL
// Process
NSString *itemTitle = item.title ? [item.title stringByConvertingHTMLToPlainText] : #"[No Title]";
NSString *itemSummary = item.summary ? [item.summary stringByConvertingHTMLToPlainText] : #"[No Summary]";
// Set
cell.textLabel.font = [UIFont boldSystemFontOfSize:15];
cell.textLabel.text = itemTitle;
NSMutableString *subtitle = [NSMutableString string];
if (item.date) [subtitle appendFormat:#"%#: ", [formatter stringFromDate:item.date]];
[subtitle appendString:itemSummary];
cell.detailTextLabel.text = subtitle;
}
return cell;
}
Best Regards
While parsing every element the parser will return a whitespace character as a response because of new line / tabbing / carriage returns. If you have implemented a call back methods (delegates) of parser then check for null values, and i donno where you have implemented(in the sense,in which parser delegate method has this) the very first snippet.
I wrote this code for the first UIPickerView
- (void)viewDidLoad
NSURL *url = [NSURL URLWithString:
#"http://localhost:8080/Data/resources/converter.country/"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request startAsynchronous];
// countrys = [[UIPickerView alloc] init];
countrys.delegate = self;
countrys.dataSource = self;
countrys.showsSelectionIndicator = YES;
countryField.inputView=countrys;
- (NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
NSString *codeCity;
codeCity=[countriesArray objectAtIndex:row];
return codeCity;
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return [countriesCodeArray count];
}
And then i wanted to make another UIPickerView with cities . I wrote this
citys.delegate = self;
citys.dataSource = self;
citys.showsSelectionIndicator = YES;
cityField.inputView=citys;
But when i click on it i have countries list . How should i change the datasource ? And how to use the default function of the UIPickerView, like numberOfComponentsInPickerView , numberOfRowsInComponent: ... with the second UIPickerView ?
You can assign tag to your pickerviews and then can check these tags in datasource/delegate methods
citysPickerview.tag = 2
otherPickerview.tag = 1
// then you can check for these tags in pickerview datasource/delegate methods like this -
- (NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
NSString *title;
if (pickerview.tag == 1) // this is otherPickerview
{
title=[countriesArray objectAtIndex:row]; // your logic to get title for otherpickerview
}
else if (pickerview.tag == 2) // this is citysPickerview
{
title=[countriesArray objectAtIndex:row]; // your logic to get title for cityspickerview
}
return title;
}
You should follow this same mechanism in your all datasource/delegate code :)
What you could do is set tag for the 2 UIPickerView, like so - [countryPicker setTag:1], use these tags to distinguish between the 2 picker views.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component
{
if([pickerView tag] == 1)
return [countryNames count];
else
return [cityNames count];
}
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
if([pickerView tag] == 1)
return [countryNames objectAtIndex:row];
else
return [cityNames count];
}
For a simpler solution, just compare the pickerView pointer. That way you save the additional complexity and maintenance of using tags.
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
NSInteger numberOfRows = 0;
if (pickerView == countrys) {
numberOfRows = [countriesCodeArray count];
}
else if (pickerView == citys) {
numberOfRows = [citysCodeArray count];
}
return numberOfRows;
}
Note: This answer is based on giuseppe's comment.
I'm making an app that uses the picker to let the user pick age and few other inputs. for eg: i have a button age, when the user clicks it, the picker shows the age. i managed to add individual picker for all the inputs, how ever i'm having problems setting different arrays for each picker.
- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
if (pickerview == picker) {
return [pickerViewArray objectAtIndex:row];
}
else if (pickerview == stagepicker)
return [stagepickerarray objectAtInde:row];
}
}
- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component {
if (thePickerView == picker){ return [pickerViewArray count]; }
else if (thePickerView == stagepicker){ [stagepickerarray count]; }
}
the above method isn't working for me !. Am I doing this right ?
- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
if (pickerview == picker) {
Doesn't it sound like pickerview should be written thePickerView instead?
return [stagepickerarray objectAtInde:row];
Doesn't it sound like objectAtInde should be objectAtIndex?
else if (thePickerView == stagepicker){ [stagepickerarray count]; }
Doesn't it sound like a return is missing somewhere?
Why not use one UIPickerView with multiple components? Something along the lines of:
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
NSInteger numberOfRows;
if (component == 0) {
numberOfRows = [anArray count];
}
else if(component == 1) {
numberOfRows = [anotherArray count];
}
else {
numberOfRows = [aThirdArray count];
}
return numberOfRows;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
NSString *stringIndex = [NSString stringWithFormat:#"TEST"];
if(component == 0) {
return stringIndex = [anArray objectAtIndex:row];
}
else if(component == 1) {
return stringIndex = [anotherArray objectAtIndex:row];
}
else {
return stringIndex = [aThirdArray objectAtIndex:row];
}
return stringIndex;
}
I am using two forms of text validation (one when they click Next, another when they manually select the next text field to enter) and it's been working perfect. However, the last text field isn't getting error checked and I can't figure it out.
You can see the issue in this video on the last text field (http://screencast.com/t/ODJiOTAwMzA). The previous four work fine as you can see, but the bottom not so much.
Here is my code:
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if (textField == txtUserName)
{
NSString *userNameOne = txtUserName.text;
double numOne = [userNameOne doubleValue];
if(numOne < 30 || numOne > 80)
{
//foo
[txtUserName becomeFirstResponder];
txtUserName.text = nil;
}
else
{
[txtUserName2 becomeFirstResponder];
}
}
else if (textField == txtUserName2)
{
NSString *userNameThree = txtUserName2.text;
float numTwo = [userNameThree doubleValue];
if (numTwo < 20 || numTwo > 32)
{
//foo
[txtUserName2 becomeFirstResponder];
txtUserName2.text = nil;
}
else
{
[txtUserName3 becomeFirstResponder];
}
}
else if (textField == txtUserName3)
{
NSString *userNameThree = txtUserName3.text;
float numThree = [userNameThree doubleValue];
if (numThree < 475 || numThree > 650)
{
//foo
[txtUserName3 becomeFirstResponder];
txtUserName3.text = nil;
}
else
{
[txtUserName4 becomeFirstResponder];
}
}
else if (textField == txtUserName4)
{
NSString *userNameFour = txtUserName4.text;
double numFour = [userNameFour doubleValue];
if (numFour < 0.5 || numFour > 3.00)
{
//foo
[txtUserName4 becomeFirstResponder];
txtUserName4.text = nil;
}
else
{
[txtUserName5 becomeFirstResponder];
}
}
else if (textField == txtUserName5)
{
NSString *userNameFive = txtUserName5.text;
double numFive = [userNameFive doubleValue];
if (numFive > 1)
{
//foo
}
}
return NO;
}
and here
if (textField == txtUserName)
{
NSString *userNameOne = txtUserName.text;
double numOne = [userNameOne doubleValue];
if(numOne < 30 || numOne > 80)
{
//foo
[txtUserName becomeFirstResponder];
txtUserName.text = nil;
}
else
{
[txtUserName2 becomeFirstResponder];
}
}
else if (textField == txtUserName2)
{
NSString *userNameThree = txtUserName2.text;
float numTwo = [userNameThree doubleValue];
if (numTwo < 20 || numTwo > 32)
{
//foo
[txtUserName2 becomeFirstResponder];
txtUserName2.text = nil;
}
else
{
[txtUserName3 becomeFirstResponder];
}
}
else if (textField == txtUserName3)
{
NSString *userNameThree = txtUserName3.text;
float numThree = [userNameThree doubleValue];
if (numThree < 475 || numThree > 650)
{
//fo
[txtUserName3 becomeFirstResponder];
txtUserName3.text = nil;
}
else
{
[txtUserName4 becomeFirstResponder];
}
}
else if (textField == txtUserName4)
{
NSString *userNameFour = txtUserName4.text;
double numFour = [userNameFour doubleValue];
if (numFour < 0.5 || numFour > 3.00)
{
//foo
[txtUserName4 becomeFirstResponder];
txtUserName4.text = nil;
}
else
{
[txtUserName5 becomeFirstResponder];
}
}
else if (textField == txtUserName5)
{
NSString *userNameFive = txtUserName5.text;
double numFive = [userNameFive doubleValue];
if (numFive > 1)
{
//foo
}
else
{
[txtUserName5 becomeFirstResponder];
}
}
If your interface is in Interface Builder, is the outlet for txtUserName5 hooked up?
For your fifth text field, why don't you have these lines after "foo" like you do for the other text fields?
if (numFive > 1)
{
//foo
[txtUserName5 becomeFirstResponder];
txtUserName5.text = nil;
}
Also, for your else clause, rather than become first responder again, you should resign first responder (to dismiss the keyboard):
else
{
//[txtUserName5 becomeFirstResponder];
[txtUserName5 resignFirstResponder];
return YES;
}