Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to notify React Native that the size of a custom view has changed?

I'm writing a custom view for React Native iOS.

Basically I have to make the text as large as possible (based on the view of the current view). I've done it by overriding reactSetFrame and changing the frame. The only issue is that the position of the view is wrong, here's a screenshot:

overlapping views

It seems that the "layout manager" of react native thinks that the views have height 0.

Here the code:

- (void)reactSetFrame:(CGRect)frame {
  [super reactSetFrame:frame];

  NSLog(@"react set frame %@", NSStringFromCGRect(frame));

  [self fitText:self.text];
}

- (void)fitText:(NSString *)text {
    // ... get the correct font size and expected size    
    [self setFont:font];

    CGRect newFrame = self.frame;

    newFrame.size.height = expectedLabelSize.height;

    NSLog(@"new frame is %@", NSStringFromCGRect(newFrame));

    self.frame = newFrame;
}

basically when the frame changes I'm updating the frame with the correct dimensions based on the text that was passed.

The logs output is this:

2017-06-25 16:43:16.434 ABC[44836:6551225] react set frame {{0, 0}, {375, 0}}
2017-06-25 16:43:16.435 ABC[44836:6551225] new frame is {{0, 0}, {375, 69.197000000000017}}
2017-06-25 16:43:16.435 ABC[44836:6551225] react set frame {{0, 0}, {375, 0}}
2017-06-25 16:43:16.436 ABC[44836:6551225] new frame is {{0, 0}, {375, 85.996999999999986}}

I've tried calling reactSetFrame with the new frame again but it is not working. Is there a way to tell React Native that the size of a view has changed?

like image 795
patrick Avatar asked Jun 25 '17 15:06

patrick


People also ask

How do I change the view size in React Native?

The general way to set the dimensions of a component is by adding a fixed width and height to style. All dimensions in React Native are unitless, and represent density-independent pixels.

How do I get the size of a view in React Native?

import { Dimensions } from 'react-native'; You can get the application window's width and height using the following code: const windowWidth = Dimensions. get('window').

How do you get parent view height in React Native?

To get the parent height and width in React: Set the ref prop on the element. In the useEffect hook, update the state variables for the height and width. Use the offsetHeight and offsetWidth properties to get the height and width of the element.

What is onLayout in view React Native?

onLayout ​ This event is fired immediately once the layout has been calculated, but the new layout may not yet be reflected on the screen at the time the event is received, especially if a layout animation is in progress. Type.


1 Answers

So I finally found a way to do this; basically react native utilise a shadow view to get the layout information. So I had to add this code to my manager

- (RCTShadowView *)shadowView
{
  return [FitTextShadowView new];
}

which is basically telling what's the shadow view for my component.

Then I had to change the implementation of the measure function that is used by Yoga to get the correct height:

@implementation FitTextShadowView

static YGSize RCTMeasure(YGNodeRef node, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode)
{
  FitTextShadowView *shadowText = (__bridge FitTextShadowView *)YGNodeGetContext(node);
  YGSize result;

  result.width = width;
  result.height = [shadowText getHeight:shadowText.text thatFits:width];
  return result;
}

- (instancetype)init
{
  if ((self = [super init])) {
    YGNodeSetMeasureFunc(self.yogaNode, RCTMeasure);
  }
  return self;
}

@end
like image 75
patrick Avatar answered Dec 08 '22 05:12

patrick