react-native-shadow icon indicating copy to clipboard operation
react-native-shadow copied to clipboard

Do I have to know previously what will be my View dimensions?

Open zygama opened this issue 6 years ago • 12 comments

Hello,

all is in the title, I would like to know if for using this lib I need to know in advance what will be the height and the width of my View? Because it's not my case, my View can have elements added or deleted.

Is there a workaround for my case?

Thank you :)

zygama avatar Apr 26 '18 22:04 zygama

I'm also facing this issue. @zygama have you been able to figure it out?

chinookng avatar Apr 28 '18 00:04 chinookng

Not yet...

zygama avatar Apr 28 '18 16:04 zygama

Has there been a solution for this yet?

ws7one avatar Jan 21 '19 08:01 ws7one

Has anyone found a solution to this yet? @zygama @ws7one @chinookng

jcorkhill avatar Apr 13 '19 02:04 jcorkhill

hey guys, I believe onLayout will resolve your issue. That event let you know view's dimensions. Please take a look next video: https://caster.io/lessons/advanced-react-native-getting-the-screen-or-a-views-dimensions

hardrese7 avatar May 10 '19 17:05 hardrese7

code example:

import React from 'react';
import { BoxShadow } from 'react-native-shadow';


function getShadowSettings(width, height) {
  return {
    width: width,
    height: height,
    color: colors.third,
    border: 6,
    opacity: 0.1,
    x: 0,
    y: 1,
  };
}

class ShadowBox extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      width: 0,
      height: 0,
      calculated: false,
    };
  }

  render() {
     const { width, height, calculated } = this.state;
    const { children } = this.props;
    const childrenWithProps = React.Children.map(children, child =>
      React.cloneElement(child, {
        onLayout: e => {
          const { width, height } = e.nativeEvent.layout;
          this.setState({ width, height, calculated: true });
        },
      }),
    );
    if (!calculated) {
      return childrenWithProps;
    }
    const shadowSettings = getShadowSettings(width, height);
    return <BoxShadow setting={shadowSettings}>{childrenWithProps}</BoxShadow>;
}

hardrese7 avatar May 11 '19 15:05 hardrese7

@hardrese7 Thanks for the information and the code snippet. I'll try it later today and get back to you.

jcorkhill avatar May 11 '19 18:05 jcorkhill

@JamieCorkhill You are welcome, I faced with the same issue today :) There is just one requirement for ShadowBox component, it should have only one child now.

hardrese7 avatar May 11 '19 18:05 hardrese7

@hardrese7 I've tried the snippet, though it's completely messing up my layout.

canpoyrazoglu avatar Jun 30 '19 10:06 canpoyrazoglu

@canpoyrazoglu try the new version:

import React from 'react';
import { BoxShadow } from 'react-native-shadow';
import { View } from 'react-native';

export function getShadowSettings(width, height) {
  return {
    width: width,
    height: height,
    color: '#18304C',
    border: 6,
    opacity: 0.05,
    x: 0,
    y: 1,
  };
}

class ShadowBox extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      width: 0,
      height: 0,
      calculated: false,
    };
  }

  onLayout(e) {
    const { width, height } = e.nativeEvent.layout;
    this.setState({ width, height, calculated: true });
  }

  render() {
    const { children, shadowSettings: customShadowSettings = {} } = this.props;
    if (React.Children.count(children) < 1) {
      throw Error('ShadowBox should have at least one child');
    }
    let childrenWithProps = children;
    if (React.Children.count(childrenWithProps) > 1) {
      childrenWithProps = <View>{children}</View>;
    }
    childrenWithProps = React.cloneElement(
      React.Children.only(childrenWithProps),
      {
        onLayout: this.onLayout.bind(this),
      },
    );
    const { width, height, calculated } = this.state;
    if (!calculated) {
      return childrenWithProps;
    }
    const shadowSettings = {
      ...getShadowSettings(width, height),
      ...customShadowSettings,
    };
    return (
      <View {...this.props}>
        <BoxShadow setting={shadowSettings}>{childrenWithProps}</BoxShadow>
      </View>
    );
  }
}

hardrese7 avatar Jul 01 '19 16:07 hardrese7

@hardrese7 nope, still messing it up (though comparably better than the first one).

It also errors on line React.Children.only(childrenWithProps) (though runs anyway).

canpoyrazoglu avatar Jul 02 '19 06:07 canpoyrazoglu

I think I'll give up on this library and just apply a lame stretched PNG shadow below my views.

canpoyrazoglu avatar Jul 02 '19 06:07 canpoyrazoglu