@@ -37,6 +37,7 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge
3737 _needsUpdateView = YES ;
3838
3939 YGNodeSetMeasureFunc (self.yogaNode , RCTBaseTextInputShadowViewMeasure);
40+ YGNodeSetBaselineFunc (self.yogaNode , RCTTextInputShadowViewBaseline);
4041 }
4142
4243 return self;
@@ -167,7 +168,7 @@ - (void)uiManagerWillPerformMounting
167168
168169#pragma mark -
169170
170- - (CGSize) sizeThatFitsMinimumSize : (CGSize) minimumSize maximumSize : (CGSize) maximumSize
171+ - (NSAttributedString *) measurableAttributedText
171172{
172173 // Only for the very first render when we don't have `_localAttributedText`,
173174 // we use value directly from the property and/or nested content.
@@ -187,6 +188,13 @@ - (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximu
187188 attributedText = [[NSAttributedString alloc ] initWithString: text attributes: self .textAttributes.effectiveTextAttributes];
188189 }
189190
191+ return attributedText;
192+ }
193+
194+ - (CGSize)sizeThatFitsMinimumSize : (CGSize)minimumSize maximumSize : (CGSize)maximumSize
195+ {
196+ NSAttributedString *attributedText = [self measurableAttributedText ];
197+
190198 if (!_textStorage) {
191199 _textContainer = [NSTextContainer new ];
192200 _textContainer.lineFragmentPadding = 0.0 ; // Note, the default value is 5.
@@ -209,6 +217,26 @@ - (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximu
209217 };
210218}
211219
220+ - (CGFloat)lastBaselineForSize : (CGSize)size
221+ {
222+ NSAttributedString *attributedText = [self measurableAttributedText ];
223+
224+ __block CGFloat maximumDescender = 0.0 ;
225+
226+ [attributedText enumerateAttribute: NSFontAttributeName
227+ inRange: NSMakeRange (0 , attributedText.length)
228+ options: NSAttributedStringEnumerationLongestEffectiveRangeNotRequired
229+ usingBlock:
230+ ^(UIFont *font, NSRange range, __unused BOOL *stop) {
231+ if (maximumDescender > font.descender ) {
232+ maximumDescender = font.descender ;
233+ }
234+ }
235+ ];
236+
237+ return size.height + maximumDescender;
238+ }
239+
212240static YGSize RCTBaseTextInputShadowViewMeasure (YGNodeRef node, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode)
213241{
214242 RCTShadowView *shadowView = (__bridge RCTShadowView *)YGNodeGetContext (node);
@@ -253,4 +281,18 @@ static YGSize RCTBaseTextInputShadowViewMeasure(YGNodeRef node, float width, YGM
253281 };
254282}
255283
284+ static float RCTTextInputShadowViewBaseline (YGNodeRef node, const float width, const float height)
285+ {
286+ RCTBaseTextInputShadowView *shadowTextView = (__bridge RCTBaseTextInputShadowView *)YGNodeGetContext (node);
287+
288+ CGSize size = (CGSize){
289+ RCTCoreGraphicsFloatFromYogaFloat (width),
290+ RCTCoreGraphicsFloatFromYogaFloat (height)
291+ };
292+
293+ CGFloat lastBaseline = [shadowTextView lastBaselineForSize: size];
294+
295+ return RCTYogaFloatFromCoreGraphicsFloat (lastBaseline);
296+ }
297+
256298@end
0 commit comments