Search code examples
iosobjective-ciphoneuitableviewuipickerview

UIPickerView in UITableView


First of all: I know that some people already posted topics like that, but nobody gave a clear answer in all those topics.

I have a settings-UITableView in my application. Now i want to add a TableViewCell where i can choose between some numbers with a UIPickerView.

In the tableView didSelectRowAtIndexPath method i created the if statement for the right cell

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

    if (indexPath.row == 1){

    }
}

How can i add a UIPickerView for this cell? It should slide up from the bottom and it would be nice if there is something like a "done" button.


Solution

  • This is also based on your other question, so I am including those functionalities here as well (i.e. the switch).

    In your YourTableViewController.h

    set:

    @interface YourTableViewViewController : UITableViewController <UIPickerViewDataSource, UIPickerViewDelegate>
    

    In your YourTableViewController.m

    Paste this code:

    @interface YourTableViewViewController ()
    @property NSInteger toggle;
    @property (strong, nonatomic) UIPickerView *pickerView;
    @end
    
    @implementation YourTableViewViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        self.toggle = 0;
        self.pickerView = [[UIPickerView alloc] initWithFrame:(CGRect){{0, 0}, 320, 480}];
        self.pickerView.delegate = self;
        self.pickerView.dataSource = self;
        self.pickerView.center = (CGPoint){160, 640};
        self.pickerView.hidden = YES;
        [self.view addSubview:self.pickerView];
    }
    
    #pragma mark - Table view data source
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        // Return the number of rows in the section.
        return 2;    
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *CellIdentifier = @"Cell";
    
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    
        if(cell == nil)
        {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
        }
        if(indexPath.row == 0)
        {
            [cell.contentView addSubview:self.mySwitch];
        }
        if(indexPath.row == 1)
        {
            cell.textLabel.textColor = [UIColor darkGrayColor];
            if(self.toggle == 0)
            {
                cell.textLabel.text = @"Choose a number";
            }
            else
            {
                cell.textLabel.text = @"Cancel";
            }
        }
        // Configure the cell...
    
        return cell;
    }
    
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if(indexPath.row == 1)
        {
            if(self.toggle == 0)
            {
                self.toggle = 1;
                [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:YES];
                [self bringUpPickerViewWithRow:indexPath];
            }
            else
            {
                self.toggle = 0;
                [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:YES];
                [self hidePickerView];
            }
        }
    }
    
    - (void)bringUpPickerViewWithRow:(NSIndexPath*)indexPath
    {
        UITableViewCell *currentCellSelected = [self.tableView cellForRowAtIndexPath:indexPath];
        [UIView animateWithDuration:1.0f
                              delay:0.0f
                            options:UIViewAnimationOptionCurveEaseInOut
                         animations:^
                         {
                             self.pickerView.hidden = NO;
                             self.pickerView.center = (CGPoint){currentCellSelected.frame.size.width/2, self.tableView.frame.origin.y + currentCellSelected.frame.size.height*4};
                         }
                         completion:nil];
    }
    
    - (void)hidePickerView
    {
        [UIView animateWithDuration:1.0f
                              delay:0.0f
                            options:UIViewAnimationOptionCurveEaseInOut
                         animations:^
         {
             self.pickerView.center = (CGPoint){160, 800};
         }
                         completion:^(BOOL finished)
         {
             self.pickerView.hidden = YES;
         }];
    }
    
    - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
    {
        self.toggle = 0;
        [self.tableView reloadData];
        [self hidePickerView];
        NSLog(@"row selected:%ld", (long)row);
    }
    
    - (NSString*) pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
    {
        return [NSString stringWithFormat:@"%d", row+1];
    }
    
    - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
    {
        return 1;
    }
    
    - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
    {
        return 10;
    }
    
    @end
    
    Tested.
    

    Addendum:

    Also, in your storyboard, change the separator for YourTableView to None (looks better in your case here).

    Table View Separator:

    in viewDidLoad, add:

    self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
    

    And in bringUpPickerViewWithRow

    after:

    UITableViewCell *currentCellSelected = [self.tableView cellForRowAtIndexPath:indexPath];
    

    add:

    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    [self.tableView setNeedsDisplay];
    

    And lastly, in hidePickerView, add:

    self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
    [self.tableView setNeedsDisplay];