Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
zygama opened this issue Apr 26, 2018 · 12 comments
Open

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

zygama opened this issue Apr 26, 2018 · 12 comments

Comments

@zygama
Copy link

zygama commented Apr 26, 2018

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 :)

@chinookng
Copy link

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

@zygama
Copy link
Author

zygama commented Apr 28, 2018

Not yet...

@ws7one
Copy link

ws7one commented Jan 21, 2019

Has there been a solution for this yet?

@jcorkhill
Copy link

jcorkhill commented Apr 13, 2019

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

@hardrese7
Copy link

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
Copy link

hardrese7 commented May 11, 2019

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>;
}

@jcorkhill
Copy link

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

@hardrese7
Copy link

@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.

@canpoyrazoglu
Copy link

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

@hardrese7
Copy link

hardrese7 commented Jul 1, 2019

@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>
    );
  }
}

@canpoyrazoglu
Copy link

@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
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants