|
// |
|
// RCTUIManager+TextView.m |
|
// Tasker |
|
// |
|
// Created by Brian Leonard on 7/31/15. |
|
// |
|
|
|
#import <UIKit/UIKit.h> |
|
#import "RCTUIManager.h" |
|
#import "RCTSparseArray.h" |
|
#import "UIView+React.h" |
|
|
|
|
|
@interface RCTUIManager (TextView) |
|
|
|
@end |
|
|
|
@implementation RCTUIManager (TextView) |
|
|
|
/** |
|
* Returns information about the content inside of a RCTTextView |
|
*/ |
|
RCT_EXPORT_METHOD(measureTextHeight:(NSNumber *)reactTag |
|
callback:(RCTResponseSenderBlock)callback) |
|
{ |
|
if (!callback) { |
|
RCTLogError(@"Called measure with no callback"); |
|
return; |
|
} |
|
|
|
[self addUIBlock:^(__unused RCTUIManager *uiManager, RCTSparseArray *viewRegistry) { |
|
UIView *view = viewRegistry[reactTag]; |
|
if (!view) { |
|
RCTLogError(@"measureTextContent cannot find view with tag #%@", reactTag); |
|
return; |
|
} |
|
|
|
UIView *rootView = view; |
|
while (rootView && ![rootView isReactRootView]) { |
|
rootView = rootView.superview; |
|
} |
|
|
|
UITextView *textView = nil; |
|
NSArray *subviews = [view subviews]; |
|
|
|
for(UIView *subview in subviews) { |
|
if ([subview isKindOfClass:[UITextView class]]) { |
|
UITextView * test = (UITextView *)subview; |
|
if (![test isHidden]) { // placeholder is hidden |
|
textView = test; |
|
break; |
|
} |
|
} |
|
} |
|
|
|
if (!textView) { |
|
RCTLogError(@"measureTextContent cannot find UITextView from tag #%@", reactTag); |
|
return; |
|
} |
|
|
|
// http://stackoverflow.com/questions/19046969/uitextview-content-size-different-in-ios7 |
|
CGFloat measuredHeight; |
|
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) |
|
{ |
|
// This is the code for iOS 7. contentSize no longer returns the correct value, so |
|
// we have to calculate it. |
|
// |
|
// This is partly borrowed from HPGrowingTextView, but I've replaced the |
|
// magic fudge factors with the calculated values (having worked out where |
|
// they came from) |
|
|
|
CGRect frame = textView.bounds; |
|
|
|
// Take account of the padding added around the text. |
|
|
|
UIEdgeInsets textContainerInsets = textView.textContainerInset; |
|
UIEdgeInsets contentInsets = textView.contentInset; |
|
|
|
CGFloat leftRightPadding = textContainerInsets.left + textContainerInsets.right + textView.textContainer.lineFragmentPadding * 2 + contentInsets.left + contentInsets.right; |
|
CGFloat topBottomPadding = textContainerInsets.top + textContainerInsets.bottom + contentInsets.top + contentInsets.bottom; |
|
|
|
frame.size.width -= leftRightPadding; |
|
frame.size.height -= topBottomPadding; |
|
|
|
NSString *textToMeasure = textView.text; |
|
if ([textToMeasure hasSuffix:@"\n"]) |
|
{ |
|
textToMeasure = [NSString stringWithFormat:@"%@-", textView.text]; |
|
} |
|
|
|
// NSString class method: boundingRectWithSize:options:attributes:context is |
|
// available only on ios7.0 sdk. |
|
|
|
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; |
|
[paragraphStyle setLineBreakMode:NSLineBreakByWordWrapping]; |
|
|
|
NSDictionary *attributes = @{ NSFontAttributeName: textView.font, NSParagraphStyleAttributeName : paragraphStyle }; |
|
|
|
CGRect size = [textToMeasure boundingRectWithSize:CGSizeMake(CGRectGetWidth(frame), MAXFLOAT) |
|
options:NSStringDrawingUsesLineFragmentOrigin |
|
attributes:attributes |
|
context:nil]; |
|
|
|
measuredHeight = ceilf(CGRectGetHeight(size) + topBottomPadding); |
|
} |
|
else |
|
{ |
|
measuredHeight = textView.contentSize.height; |
|
} |
|
|
|
callback(@[ @(measuredHeight) ]); |
|
}]; |
|
} |
|
|
|
@end |
This comment has been minimized.
kevando commentedAug 21, 2016
Do you mind if I ask how to install this? I've never created a bridge module before and all my attempts to add this .m file have not worked. Thanks!