Skip to content

Commit 107c90f

Browse files
committed
feat: use usedRect in layout subviews
1 parent a1fbe75 commit 107c90f

3 files changed

Lines changed: 25 additions & 6 deletions

File tree

ios/EnrichedTextInputView.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ NS_ASSUME_NONNULL_BEGIN
4040
- (NSArray<NSNumber *> *)getPresentStyleTypesFrom:(NSArray<NSNumber *> *)types
4141
range:(NSRange)range;
4242
- (CGSize)measureInitialSizeWithMaxWidth:(CGFloat)maxWidth;
43+
- (void)commitSize:(CGSize)size;
4344
@end
4445

4546
NS_ASSUME_NONNULL_END

ios/EnrichedTextInputView.mm

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -673,16 +673,15 @@ - (void)updateState:(State::Shared const &)state
673673
// componentView) so we need to run a single height calculation for any
674674
// initial values
675675
if (oldState == nullptr) {
676-
[self measureAndCommitSize];
676+
[self commitSize:textView.textContainer.size];
677677
}
678678
}
679679

680-
- (void)measureAndCommitSize {
680+
- (void)commitSize:(CGSize)size {
681681
if (_state == nullptr) {
682682
return;
683683
}
684-
CGSize size =
685-
[self measureInitialSizeWithMaxWidth:textView.bounds.size.width];
684+
686685
auto selfRef = wrapManagedObjectWeakly(self);
687686
facebook::react::Size newSize{.width = size.width, .height = size.height};
688687
_state->updateState(
@@ -1366,8 +1365,6 @@ - (void)anyTextMayHaveBeenModified {
13661365
}
13671366
}
13681367

1369-
// update height on each character change
1370-
[self measureAndCommitSize];
13711368
// update active styles as well
13721369
[self tryUpdatingActiveStyles];
13731370
}

ios/inputTextView/InputTextView.mm

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,19 @@
44
#import "TextInsertionUtils.h"
55
#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
66

7+
// for some reason UIKit may produce different size with the same text
8+
// the difference is always ~0.5
9+
static const CGFloat Epsilon = 0.5;
10+
11+
static inline BOOL CGSizeAlmostEqual(CGSize firstSize, CGSize secondSize,
12+
CGFloat epsilon) {
13+
return fabs(firstSize.width - secondSize.width) < epsilon &&
14+
fabs(firstSize.height - secondSize.height) < epsilon;
15+
}
16+
717
@implementation InputTextView {
818
UILabel *placeholderView;
19+
CGSize _lastCommittedSize;
920
};
1021

1122
- (instancetype)initWithFrame:(CGRect)frame {
@@ -18,6 +29,7 @@ - (instancetype)initWithFrame:(CGRect)frame {
1829
self.textContainer.lineFragmentPadding = 0;
1930
self.scrollEnabled = YES;
2031
self.scrollsToTop = NO;
32+
_lastCommittedSize = CGSizeZero;
2133
}
2234
return self;
2335
}
@@ -212,6 +224,15 @@ - (void)layoutSubviews {
212224
[placeholderView sizeThatFits:textFrame.size].height;
213225
textFrame.size.height = MIN(placeholderHeight, textFrame.size.height);
214226
placeholderView.frame = textFrame;
227+
CGSize newSize =
228+
[self.layoutManager usedRectForTextContainer:self.textContainer].size;
229+
if (CGSizeAlmostEqual(newSize, _lastCommittedSize, Epsilon)) {
230+
return;
231+
}
232+
233+
_lastCommittedSize = newSize;
234+
235+
[_input commitSize:newSize];
215236
}
216237

217238
@end

0 commit comments

Comments
 (0)