Disable delegate method for UIPickerView/UITableView on conditional case - iphone

I want to disable below delegate method for some condition
-(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
let say if(x==YES) then only above delegate method hit else it won't respond.
Please let me know your suggestion.

Override respondsToSelector: and return NO in case of You does not want to call this method:
- (BOOL)respondsToSelector:(SEL)selector
{
if (selector == #selector(pickerView:viewForRow:forComponent:reusingView:))
{
if(your_Condition)
{
return YES;
}
eles
{
return NO;
}
}
return [super respondsToSelector:selector];
}
So you're implementing the delegate method as normally. When the picker view is asking your delegate if it understands the message you're simply lying to it.

There are two ways you can do it.
1) Make Delegate Null
Set a condition when you do not want to call the method and at that place make delegate = nill.
And again Reset it delegate =self when needs to call the method.
The second method which I must say Better one
2) Use flag inside the Delegate method
Try to implement if-condition (Flag) inside the method and set its TRUE and FALSE values as per requirement.
for ex.
-(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
if(x == YES) {
// Only this code need to implement
} else {
return;
}
}

Related

Disable delegate methods depending on iOS version

I'm using some UIPickerView delegate methods only for the brand-new-Ive-modified iOS under NDA, e.g.
-(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
I don't want to implement them for iOS6, to preserve default iOS behavior, so a condition inside the method won't work. How to do it?
In your delegate, override respondsToSelector: and return NO in case of old OS:
- (BOOL)respondsToSelector:(SEL)selector
{
if (selector == #selector(pickerView:viewForRow:forComponent:reusingView:))
return MyFunctionThatChecksIosVersionIsMinimum7();
return [super respondsToSelector:selector];
}
So you're implementing the delegate method normally. When the picker view is asking your delegate if it understands the message you're simply lying to it.

Two PickerViews with different values

This is my code for two pickerviews in one view controller. However its not working for me.
#pragma mark UIPickerViewDelegate methods
//PickerViewController.m
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component {
switch ([thePickerView tag]) {
case 1: //purpose picker
return [m_arrPurpose count];
case 2: //second picker
return [m_arrSweep count];
default:
return 0;
break;
}
}
- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
switch ([thePickerView tag]) {
case 1: //purpose picker
{
//cost.text = #"Test";
Purpose *prp = [m_arrPurpose objectAtIndex:row];
return [prp m_purposeName];
}
case 2: //second picker
{
OpenActivity *opn = [m_arrSweep objectAtIndex:row];
return [opn m_ahhaName];
}
default:
return #"";
break;
}
}
can any1 help me with this please..
thanks
It sounds like either your tags aren't set correctly or you havent connected the datasource and delegate methods for both pickers.
Add some NSLog statements in the numberOfRowsInComponent and titleForRow: methods.
Include the picker view object and the picker view's tag in the log, e.g.
NSLog(#"Rows in component for %#, tag %d",thePickerView,[thePickerView tag]);
And a different text in the titleForRow.
You should see two different objects - if not, your delegate and datasource are not connected. You should see tags 1 and 2 - if not, your tags are not set properly.
With this problem there was nothing wrong with my code It's just that I forgot to set tag's value to 1 and 2 in XIB.

UIPicker noob question - If I click on first item in the picker, the result is null - all other items are fine

I have a UIPicker with 7 items in it. (only one component)... If I click on the first item in the Picker (without ANY SCROLLING of the picker), the text results I get back are null.
However, If I so much as "tug" downward on the list and THEN CLICK item #1 it works fine.
If I click ANY other item, it always returns the right result. Of course, the list has to scroll in order for those items to get selected.
What is happening to cause this? Is there a delegate function I need to call? Is there some way to default the selection to the first item in the list, if they never click anything?
Thanks,
Phil
Here is a snippet from "viewdidload" in my .m
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#">>> Entering %s <<<", __PRETTY_FUNCTION__);
listOfTerms=[[NSArray alloc]initWithObjects:
#"Fall Semester",#"Spring Semester",#"Summer Session",#"Q1",#"Q2",#"Q3",#"Q4",nil];
...
...
Here are the other 4 UIPickerView delegate functions I have defined.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component {
return [listOfTerms count];
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [listOfTerms objectAtIndex:row];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row
inComponent:(NSInteger)component {
selectedTerm =[[NSString alloc]
initWithFormat:#"%#",
[listOfTerms objectAtIndex:row]];
}
pickerView:didSelectRow:inComponent: is only called when the picker view scrolls. So if you never scroll the view, the method never gets called and therefore selectedTerm is never set. The fix is simple, initialize selectedTerm in viewDidLoad:.
The most simple answer for all situation is to imply didSelectRow in viewDidAppear
(Please note that it is NOT viewDidLoad method)
- (void) viewDidAppear:(BOOL)animated{
[self pickerView:[self yourpickerview] didSelectRow:0 inComponent:0;
}

UIPickerView crashing when switching segemented control

I have four NSDictionaries that I would like to use to populate a pickerview depending on a segemented control.
With the code I have, the first segmented control/pickerview works fine but when I switch to the second segment the picker view only loads part of the second dictionary, that is it loads the same number of rows as it counted in the first dictionary. When I change the segmented control to the third or fourth segment it simply crashes with a sigabrt error indicating that it cannot index item43 when only 27 exist. This I suspect stems from a UItextfield population based on the upickerview row and object. I think the problem is with the way I have the data source and delegate set up.
#pragma mark -
#pragma mark UIPickerViewDelegate
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if ([wine selectedSegmentIndex] == 0)
{
return [robskeys objectAtIndex:row];
}
if ([wine selectedSegmentIndex] == 1)
{
return [esabskeys objectAtIndex:row];
}
if ([wine selectedSegmentIndex] == 2)
{
return [lebskeys objectAtIndex:row];
}
else if ([wine selectedSegmentIndex] == 3)
{
return [sbskeys objectAtIndex:row];
}
return #"Unknown title";
}
#pragma mark -
#pragma mark UIPickerViewDataSource
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if ([wine selectedSegmentIndex] == 0)
{
return robskeys.count;
}
if ([wine selectedSegmentIndex] == 1)
{
return esabskeys.count;
}
if ([wine selectedSegmentIndex] == 2)
{
return lebskeys.count;
}
else if ([wine selectedSegmentIndex] == 3)
{
return sbskeys.count;
}
return 1;
}
#pragma mark -
Any help would be much appreciated
Thank you
UPDATE
Using the following when the segmentedcontrol is changed works. Does anyone see any problems in alloc, init, release the same picker view in viewDidLoad and in this IBAction. As you may have guessed the UItextfield winespec calls the coPicker not a keypad.
-(IBAction)ValueChanged:(id)sender {
[winespec resignFirstResponder];
UIPickerView *coPicker = [[UIPickerView alloc] initWithFrame:CGRectZero];
coPicker.tag = kCountryPickerTag;
coPicker.delegate = self;
coPicker.dataSource = self;
[coPicker setShowsSelectionIndicator:YES];
winespec.inputView = countryPicker;
[winespec becomeFirstResponder];
[coPicker release];
}
Are you reloading the UIPickerView when you switch the data source? (The reloadAllComponents method should do the trick.)
Irrespective, the problem is that an "out of index" row is being selected, so you'll probably also need to use the UIPickerView's selectedRowInComponent method to select a "safe" row (the first for example) when you switch the data source.
UPDATE
In essence, when you (effectively) change the current data source via the segmented control you need to set the selectedRowInComponent to zero and call reloadAllComponents on your UIPickerView. That should sort it all out. As such you could put this within the action you use to respond to the segmented control changes.

UIPicker With View + View Tapped != Selected Row

Hey! I have a UIPicker, and I am using the function:
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row
forComponent:(NSInteger)component reusingView:(UIView *)view {
But, when you tap one of the views returned by this function, the tapped view does not become highlighed, and selected if the touch is released. How can I fix that?
Make use of this property,
pickerView.showsSelectionIndicator = YES;
at initialization.