I have an application where I regularly use a UIDatePicker
inside a table view. Therefore, I made custom DatePickerTableViewCell
class, which used to work (a couple of years ago, I don't know the exact date). Now that I'm testing everything again on iOS 14, the date picker does not react on my gestures intended to scroll the wheels. Instead, the table view seems to steal the scroll gesture. Even if I don't set the preferred style to 'Wheels', I can't interact with the date picker.
To reproduce it, you need a table view controller with enough cells to make it scrollable (which cells doesn't matter):
@implementation TableViewController
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 20;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return indexPath.row == 0 ? 216 : tableView.rowHeight;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row > 0)
return [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
return [[DatePickerTableViewCell alloc] initWithFrame:CGRectMake(0, 0, 320, 216)];
}
@end
and of course the DatePickerTableViewCell
class itself:
@interface DatePickerTableViewCell () {
UIDatePicker *datePicker;
}
@end
@implementation DatePickerTableViewCell
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake((frame.size.width - 320) / 2, 0, 320, 216)];
datePicker.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin
| UIViewAutoresizingFlexibleRightMargin;
datePicker.datePickerMode = UIDatePickerModeDate;
if (@available(iOS 13.4, *)) {
datePicker.preferredDatePickerStyle = UIDatePickerStyleWheels;
}
[self addSubview:datePicker];
}
return self;
}
@end
The date picker shows, but I'm not able to interact with it:
You're adding the UIDatePicker as a subview of the UITableViewCell subclass rather than as a subview of the UITableViewCellContentView so it's a sibling rather than child of the content view. My guess is the touches are being absorbed by the content view or the content view isn't being instantiated properly since it's never used.
The structure of your cell as it currently stands:
DatePickerTableViewCell
-- DatePicker
-- UITableViewCellContentView
Switching this line:
[self addSubview:datePicker];
to this:
[self.contentView addSubview:datePicker];
within the DatePickerTableViewCell's - (id)initWithFrame:(CGRect)frame
should allow the DatePicker to scroll properly and the structure will be:
DatePickerTableViewCell
-- UITableViewCellContentView
---- DatePicker