Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions ios/RNDateTimePicker.m
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,21 @@ - (void)setDate:(NSDate *)date {
}
}

- (CGSize)intrinsicContentSize {
CGSize size = [super intrinsicContentSize];
// iOS DatePicker requires a minimum width of 280 points for proper display
// See: https://github.com/react-native-datetimepicker/datetimepicker/issues/1014
size.width = MAX(size.width, 280);

// For inline (calendar) display style, suggest a larger width
// This helps the calendar expand to fill available width
if (@available(iOS 14.0, *)) {
if (self.preferredDatePickerStyle == UIDatePickerStyleInline) {
size.width = MAX(size.width, 375); // Standard iPhone width
}
}

return size;
}

@end
25 changes: 24 additions & 1 deletion ios/RNDateTimePickerShadowView.m
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,30 @@ static YGSize RNDateTimePickerShadowViewMeasure(YGNodeConstRef node, float width
}

size = [shadowPickerView.picker sizeThatFits:UILayoutFittingCompressedSize];
size.width += 10;
// iOS DatePicker requires a minimum width of 280 points for proper display
// See: https://github.com/react-native-datetimepicker/datetimepicker/issues/1014
size.width = MAX(size.width, 280);

// Respect the provided width constraint to allow the picker to expand to full width
// when a specific width is provided or when measuring at-most mode
if (widthMode == YGMeasureModeExactly) {
size.width = width;
} else if (widthMode == YGMeasureModeAtMost) {
// For inline/calendar style, try to use the full available width
// For other styles, use the minimum width needed
if (@available(iOS 14.0, *)) {
if (shadowPickerView.picker.preferredDatePickerStyle == UIDatePickerStyleInline) {
size.width = width; // Use full available width for calendar
} else {
size.width = MIN(size.width + 10, width);
}
} else {
size.width = MIN(size.width + 10, width);
}
} else {
// For undefined mode, add small padding
size.width += 10;
}
});

return (YGSize){
Expand Down
15 changes: 15 additions & 0 deletions ios/fabric/RNDateTimePickerComponentView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,21 @@ - (void) updateMeasurements {
}
CGSize size = [_dummyPicker sizeThatFits:UILayoutFittingCompressedSize];
size.width += 10;

// Workaround: sizeThatFits: returns incorrect height for
// UIDatePickerModeDateAndTime + UIDatePickerStyleInline (Apple bug).
// The returned height only accounts for the calendar, missing the time row.
if (@available(iOS 14.0, *)) {
if (_dummyPicker.datePickerMode == UIDatePickerModeDateAndTime &&
_dummyPicker.preferredDatePickerStyle == UIDatePickerStyleInline) {
UIDatePicker *timePicker = [UIDatePicker new];
timePicker.datePickerMode = UIDatePickerModeTime;
timePicker.preferredDatePickerStyle = UIDatePickerStyleInline;
CGSize timeSize = [timePicker sizeThatFits:UILayoutFittingCompressedSize];
size.height += timeSize.height;
}
}

auto newState = RNDateTimePickerState{RCTSizeFromCGSize(size)};
_state->updateState(std::move(newState));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,12 @@ class RNDateTimePickerComponentDescriptor final : public ConcreteComponentDescri

void adopt(ShadowNode& shadowNode) const override {
auto& pickerShadowNode = static_cast<RNDateTimePickerShadowNode&>(shadowNode);
auto& layoutableShadowNode = static_cast<YogaLayoutableShadowNode&>(pickerShadowNode);

auto state = std::static_pointer_cast<const RNDateTimePickerShadowNode::ConcreteState>(shadowNode.getState());
auto stateData = state->getData();

if(stateData.frameSize.width != 0 && stateData.frameSize.height != 0) {
layoutableShadowNode.setSize(Size{stateData.frameSize.width, stateData.frameSize.height});
if(stateData.frameSize.height != 0) {
pickerShadowNode.setMeasuredHeight(stateData.frameSize.height);
}

ConcreteComponentDescriptor::adopt(shadowNode);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ class JSI_EXPORT RNDateTimePickerShadowNode final : public ConcreteViewShadowNod
traits.set(ShadowNodeTraits::Trait::LeafYogaNode);
return traits;
}

void setMeasuredHeight(float height) const {
auto style = yogaNode_.style();
style.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(height));
yogaNode_.setStyle(style);
yogaNode_.setDirty(true);
}
};

} // namespace react
Expand Down