Search code examples
iosuitableviewios6uipickerviewuistoryboard

-[PickerViewController superview]: unrecognized selector sent to instance & TableView ->ViewController w/ Picker View


I am a novice ios programmer having some trouble push segueing from a custom UITableViewController scene to a custom UIViewController scene which contains a Picker View and implements the @required pickerview delegate/datasource methods.

[I had a screenshot here to offer more insight but I dont have the rep to post images. Imagine a tableview controller with three static rows, each offering a detail disclosure to push to the respective picker view - Image]

The issue happens at runtime when I tap on any of the table's disclosure indicators. The error returned is

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[PickerViewController superview]: unrecognized selector sent to instance."

As mentioned, LocationFilter subclasses UITableViewController and consists of just a few properties for the labels and the stepper.

The code for my picker view controller is as follows:

#import <UIKit/UIKit.h>

@interface PickerViewController : UIViewController <UIPickerViewDataSource,UIPickerViewDelegate>
{
    NSArray *sectionCandidates;
    NSArray *bankCandidates;
    NSArray *positionCandidates;
}

@property (weak, nonatomic) IBOutlet UIPickerView *sectionPicker;
@property (weak, nonatomic) IBOutlet UIPickerView *bankPicker;
@property (weak, nonatomic) IBOutlet UIPickerView *positionPicker;
@property NSArray *sectionCandidates, *bankCandidates, *positionCandidates;

@end

and the .m:

#import "PickerViewController.h"
#import "SlotMachine.h"

@implementation PickerViewController

@synthesize sectionCandidates, sectionPicker, bankCandidates, bankPicker, positionCandidates, positionPicker;

- (void)viewDidLoad
{
    [super viewDidLoad];
    sectionCandidates = [NSArray arrayWithObjects:@"A", @"B", @"C", @"D", @"E", @"F", @"G", @"H", @"I", nil];
    bankCandidates = [NSArray arrayWithObjects:@"0", @"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", nil];
    positionCandidates = [NSArray arrayWithObjects:@"0", @"1", @"2", @"3", @"4", @"5", @"6", nil];
}

// returns the number of 'columns' to display.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
    return 1;
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
    //Handle Selection
}

// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
    switch ([pickerView tag])
    {
        case 0:
            return [sectionCandidates count];
        case 1:
            return [bankCandidates count];
        case 2:
            return [positionCandidates count];
        default:
            return 0;
    }
}

// returns the label for each row
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
    switch ([pickerView tag])
    {
        case 0:
            return [sectionCandidates objectAtIndex:row];
        case 1:
            return [bankCandidates objectAtIndex:row];
        case 2:
            return [positionCandidates objectAtIndex:row];
        default:
            return @"Null";
    }
}

@end

Unfortunately picker views don't seem to get much detailed attention in terms of troubleshooting so I have not been able to find much on SO or in some iOS books that I've been going through to help me resolve this problem. I have a general idea of the possible causes for 'unrecognized selector sent to instance' but am not sure how the fixes for that apply here. I appreciate in advance any help I might receive and also apologize if I did not format properly or give enough/relevant information as this is my first post!


Solution

  • From the storyboard I see one picker view in each view picker view controller, but you declare three IBOutlet of picker view in the code. Either you need to consolidate those three view controllers in IB into one with three picker views inside, or you need to make three separate view controller subclass with only one IBOutlet UIPickerView property.

    Since you have set those picker views as properties, those tags are not necessary. You can change the checking of the tags with the checking of the picker view itself:

    - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
    {
        if (pickerView == self.sectionPicker) {
            return [sectionCandidates count];
        }
        else if (pickerView == self.bankPicker) {
            return [bankCandidates count];
        }
        else if (pickerView == self.positionPicker) {
            return [positionCandidates count];
        }
        return 0;
    }
    

    You need to make similar changes for picker view data source titleForRow:forComponent too.