react-native-vector-icons icon indicating copy to clipboard operation
react-native-vector-icons copied to clipboard

Struggling to centre an icon within a TouchableOpacity

Open alrhalford opened this issue 6 years ago • 12 comments
trafficstars

I'm trying to create a button component like so:

export class CancelButton extends React.Component {
  render() {
    const baseStyle = {
      borderRadius: 30,
      borderWidth: StyleSheet.hairlineWidth,
      width: 60,
      height: 60,
      justifyContent: 'center',
      alignItems: 'center',
    };

    return (
      <TouchableOpacity
        style={baseStyle}
        onPress={this.props.onPress}
        disabled={!this.props.active}
      >
        <Icon name="close" size={60} color="white" />
      </TouchableOpacity>
    );
  }
}

The goal is a circular button, with the cross icon centred both vertically and horizontally. However, the icon seems to have some kind of padding around it. I tried passing a style to the Icon to give it a border (just to make it visible), and the x is not centred vertically in its own border... I tried setting padding to zero, but that made no difference. Am I doing something stupid?

This is on iOS, FWIW

alrhalford avatar May 23 '19 22:05 alrhalford

@alexhalford you're not taken into consideration the borderWidth when calculating the size on "innerCircle". Basically size={60} and width={60} height={60} is enough only for the icon but not the border itself. So to actually repro the wrong behaviour you can increase the borderWidth.

To fix it, you should calculate the "innerSize" of the button where you take into consideration the borderWidth. I prepared a snack for you to take a closer look:

https://snack.expo.io/@catalinmiron/vector-icons-rounded-button

Output: IMG_7941

catalinmiron avatar May 27 '19 13:05 catalinmiron

@alexhalford please let me know if the solution from above is fixing your issue and feel free to close this issue. Thanks!

catalinmiron avatar Jun 03 '19 21:06 catalinmiron

Hello @catalinmiron, I am seeing the same issue on iOS. Just to double check, are you testing your code on Android? The issue can be simply reproduced by wrapping the icon component with a View component without any borderWidth on iOS. I think iOS is the key to reproduce it.

<View style={{ width: 28, height: 28, borderRadius: 14, alignItems: 'center', justifyContent: 'center' }} >
    < Ionicons 
        name={'ios-close'} 
        size={20} 
        color={color ? color : '#000'} />
</View>

Please check out the screenshot on iOS. Simulator Screen Shot - iPhone 8 - 2019-12-02 at 18 37 13

Please check out the screenshot for the same code on Android. Screenshot_20191202-184221

fozhao avatar Dec 02 '19 10:12 fozhao

Did anyone find a fix to this issue?

CoinCoderBuffalo avatar Jan 16 '20 18:01 CoinCoderBuffalo

I'm having the same issue on version 6.6.0, on iOS, RN 0.61.4, with Material Community Icons

tomsotte avatar Feb 04 '20 09:02 tomsotte

I don't actually understand what's wrong here :) Has anyone followed the snack that I've provided? Also, @fozhao I can't see the issue from your screenshots. Could you please be more specific?

Thanks!

catalinmiron avatar Feb 05 '20 08:02 catalinmiron

I'm seing the exact same issue on iOS only (Android is fine). There seem to be some bottom padding that gets added on iOS.

Has anyone found a fix ? @fozhao, @jjg77, @alexhalford ?

zabojad avatar Mar 31 '20 11:03 zabojad

@catalinmiron I don't see how the borderWidth could be related with that issue, given that border width is not calculated into the actual TouchableOpacity width...

zabojad avatar Mar 31 '20 11:03 zabojad

I got it to work like this:

<TouchableOpacity
         onPress={ () => props.navigation.navigate('addPost') }
         style={getStyle('floatingButton', theme)}
      >
         <Ionicons 
          name="md-create"
          size={30} 
          color={Colors[theme].accent} 
         />

      </TouchableOpacity>
const getStyle = (style, theme) => { 
  const styles = {
    floatingButton: {
      borderWidth:1,
      borderColor:'rgba(0,0,0,0.2)',
      alignItems:'center',
      justifyContent:'center',
      width:60,
      height:60,
      backgroundColor: Colors[theme].background4,
      borderRadius:100,
      alignSelf: 'flex-end',
      position: 'absolute',
      bottom: 35,
      right: 17,
      elevation: 3,
      opacity:0.8
    }
  }
  return StyleSheet.flatten(styles[style]);
};

CoinCoderBuffalo avatar Mar 31 '20 19:03 CoinCoderBuffalo

uhh, ok. I'm not sure about what exactly solves the problem in your stylesheet...

Im my case, I simply added a marginTop and marginLeft to my Icon and that kind of erased the "padding" on iOS... But that's ugly. We should find a solution right within the react-native-vector-icons lib and understand why it's happening on iOS in the first place...

zabojad avatar Apr 01 '20 07:04 zabojad

That's correct, any possible solutions on this?

quicksilverr avatar Oct 19 '22 17:10 quicksilverr

No solution that I know of... It's really a pity that's such a basic issue does not get solved...

zabojad avatar Jan 04 '23 11:01 zabojad