UIPickerView in UITableView
Solution 1
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];
Solution 2
Have you seen the sample program released with iOS 7 called DateCell? It uses a UIDatePicker, but I found it pretty straightforward to adapt it to a regular UIPickerView.
It does exactly what you're describing: edit a UITableViewCell with a picker that opens directly under the row you're editing.
Mike_NotGuilty
State-certified technical engineer and Software-Engineer. Web development (React, Angular, PHP) App development (Native, React-Native, Ionic) Microcontroller development
Updated on July 09, 2022Comments
-
Mike_NotGuilty almost 2 years
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.
-
Mike_NotGuilty over 10 yearsthanks for the answer! i get an error in the
bringUpPickerViewWithRow
method atself.pickerView = CGPoint ...
incompatible type CGPoint (aka struct CGPoint). Do you know why? -
Mike_NotGuilty over 10 yearsworks! thanks! I have more cells under this cell. is it possible that the picker doesn't slide that high? Do i have just to edit this self.pickerview.center line? is this line responsible how high the picker slides? ... ok yes it is that line, haha. :-)
-
Unheilig over 10 years@user2710855 Yes, play around with that line and you will get the height you want.
-
Mike_NotGuilty over 10 yearsone final question: is it possible that when i tap on the cell, THEN the tableview separator lines should disappear? that would be great
-
Unheilig over 10 years@user2710855 yes, let me add that in my answer.
-
Mughees Musaddiq about 10 yearsWhat if we don't want to use mySwitch? as it is giving an error.
-
Mughees Musaddiq about 10 years@Unheilig Thanks, But I replaced
cell.textLabel.text = @"Choose a number";
withcell.textLabel.text = [ASQT objectAtIndex:indexPath.row];
as I want to populate table with several questions. However it is only showing a single row. -
Mughees Musaddiq about 10 years@Unheilig
if(indexPath.row == 0)
containsmySwitch
statement that I already have commented. It isn't working. -
Mughees Musaddiq about 10 years@Unheilig I have replaced
if(indexPath.row == 0)
withif(indexPath.row != 1)
and addedcell.textLabel.text = [ASQT objectAtIndex:indexPath.row];
. When I uncomment the[cell.contentView addSubview:self.mySwitch];
it gives an errorProperty mySwith not found on object of type "YourTableViewViewController"
. However, if I comment mySwitch statement it doesn't work :( -
Mughees Musaddiq about 10 years@Unheilig Thanks, your updated code did populate the table but the
UIPickerView
is appearing only for one row. I wantUIPickerView
to appear for all the rows in the table. -
Mughees Musaddiq about 10 years@Unheilig Isn't it possible? Please suggest me a solution to this problem as I'm struggling for last couple of days to achieve this functionality.
-
Unheilig about 10 years@MugheesMusaddiq I would suggest adding your
UIPicker
to thecontentView
to the cell and make sure you implement the delegate method of yourUIPickerView
so that you could do something with theUIPicker
when it is selected. To make it look nice, one would have to set up the correct height for the cell. -
Mughees Musaddiq about 10 years@Unheilig There should be a tutorial to implement
inline pickerView
like DateCell. I'll give it a try, Thanks :)